Initial commit
This commit is contained in:
commit
ba0f56bc89
|
@ -0,0 +1,8 @@
|
||||||
|
# 8bit FPGA
|
||||||
|
|
||||||
|
An FPGA version of the 8-bit computer built by Ben Eater in his [series of videos](https://eater.net/8bit).
|
||||||
|
|
||||||
|
[Here is a blog post about it.](https://austinmorlan.com/posts/8bit_breadboard_fpga/)
|
||||||
|
|
||||||
|
![Demo](https://austinmorlan.com/posts/8bit_breadboard_fpga/media/output_7seg.gif)
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
CODE_DIR=$(pwd)/code
|
||||||
|
BUILD_DIR=$(pwd)/build
|
||||||
|
|
||||||
|
COMMAND=$1
|
||||||
|
|
||||||
|
if [ "$1" == "build" ]; then
|
||||||
|
mkdir -p $BUILD_DIR
|
||||||
|
pushd $BUILD_DIR
|
||||||
|
|
||||||
|
yosys -q -p 'synth_ice40 -top top -blif top.blif' $CODE_DIR/top.v
|
||||||
|
arachne-pnr -q -d 8k -P cm81 -o top.asc -p $CODE_DIR/pins.pcf top.blif
|
||||||
|
icepack top.asc top.bin
|
||||||
|
icetime -d lp8k -mtr top.rpt top.asc
|
||||||
|
|
||||||
|
iverilog -g2005-sv -o testbench $CODE_DIR/cpu_tb.v $CODE_DIR/cpu.v
|
||||||
|
vvp testbench
|
||||||
|
popd
|
||||||
|
elif [ "$1" == "clean" ]; then
|
||||||
|
rm -r $BUILD_DIR
|
||||||
|
elif [ "$1" == "program" ]; then
|
||||||
|
tinyprog -p $BUILD_DIR/top.bin
|
||||||
|
elif [ "$1" == "sim" ]; then
|
||||||
|
gtkwave $BUILD_DIR/testbench.vcd
|
||||||
|
else
|
||||||
|
echo "Invalid arguments"
|
||||||
|
fi
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
module seven_seg(
|
||||||
|
input wire[3:0] bcd,
|
||||||
|
output wire[6:0] segments
|
||||||
|
);
|
||||||
|
|
||||||
|
assign segments =
|
||||||
|
// ABCDEFG
|
||||||
|
(bcd == 0) ? 7'b1111110 :
|
||||||
|
(bcd == 1) ? 7'b0110000 :
|
||||||
|
(bcd == 2) ? 7'b1101101 :
|
||||||
|
(bcd == 3) ? 7'b1111001 :
|
||||||
|
(bcd == 4) ? 7'b0110011 :
|
||||||
|
(bcd == 5) ? 7'b1011011 :
|
||||||
|
(bcd == 6) ? 7'b1011111 :
|
||||||
|
(bcd == 7) ? 7'b1110000 :
|
||||||
|
(bcd == 8) ? 7'b1111111 :
|
||||||
|
(bcd == 9) ? 7'b1110011 :
|
||||||
|
7'b0000000;
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
module bin_to_bcd(
|
||||||
|
input wire[7:0] bin,
|
||||||
|
output reg[11:0] bcd);
|
||||||
|
|
||||||
|
integer i;
|
||||||
|
|
||||||
|
always @(bin) begin
|
||||||
|
bcd = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i = i+1) begin
|
||||||
|
if (bcd[3:0] > 4)
|
||||||
|
bcd[3:0] = bcd[3:0] + 3;
|
||||||
|
|
||||||
|
if (bcd[7:4] > 4)
|
||||||
|
bcd[7:4] = bcd[7:4] + 3;
|
||||||
|
|
||||||
|
if (bcd[11:8] > 4)
|
||||||
|
bcd[11:8] = bcd[11:8] + 3;
|
||||||
|
|
||||||
|
// Concatenate acts as a shift
|
||||||
|
bcd = {bcd[10:0], bin[7-i]};
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
|
@ -0,0 +1,392 @@
|
||||||
|
module cpu(
|
||||||
|
input wire clk,
|
||||||
|
input wire reset,
|
||||||
|
output reg[7:0] out
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Opcodes
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
parameter OP_NOP = 4'b0000;
|
||||||
|
parameter OP_LDA = 4'b0001;
|
||||||
|
parameter OP_ADD = 4'b0010;
|
||||||
|
parameter OP_SUB = 4'b0011;
|
||||||
|
parameter OP_STA = 4'b0100;
|
||||||
|
parameter OP_LDI = 4'b0101;
|
||||||
|
parameter OP_JMP = 4'b0110;
|
||||||
|
parameter OP_JC = 4'b0111;
|
||||||
|
parameter OP_JZ = 4'b1000;
|
||||||
|
parameter OP_OUT = 4'b1110;
|
||||||
|
parameter OP_HLT = 4'b1111;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Control Signals
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Halt
|
||||||
|
reg ctrl_ht;
|
||||||
|
always @(negedge clk) begin
|
||||||
|
if (ir[7:4] == OP_HLT && stage == 2)
|
||||||
|
ctrl_ht <= 1;
|
||||||
|
else
|
||||||
|
ctrl_ht <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
// Memory Address Register In
|
||||||
|
reg ctrl_mi;
|
||||||
|
always @(negedge clk) begin
|
||||||
|
if (stage == 0)
|
||||||
|
ctrl_mi <= 1;
|
||||||
|
else if (ir[7:4] == OP_LDA && stage == 2)
|
||||||
|
ctrl_mi <= 1;
|
||||||
|
else if (ir[7:4] == OP_ADD && stage == 2)
|
||||||
|
ctrl_mi <= 1;
|
||||||
|
else if (ir[7:4] == OP_SUB && stage == 2)
|
||||||
|
ctrl_mi <= 1;
|
||||||
|
else if (ir[7:4] == OP_STA && stage == 2)
|
||||||
|
ctrl_mi <= 1;
|
||||||
|
else
|
||||||
|
ctrl_mi <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
// RAM In
|
||||||
|
reg ctrl_ri;
|
||||||
|
always @(negedge clk) begin
|
||||||
|
if (ir[7:4] == OP_STA && stage == 3)
|
||||||
|
ctrl_ri <= 1;
|
||||||
|
else
|
||||||
|
ctrl_ri <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
// RAM Out
|
||||||
|
reg ctrl_ro;
|
||||||
|
always @(negedge clk) begin
|
||||||
|
if (stage == 1)
|
||||||
|
ctrl_ro <= 1;
|
||||||
|
else if (ir[7:4] == OP_LDA && stage == 3)
|
||||||
|
ctrl_ro <= 1;
|
||||||
|
else if (ir[7:4] == OP_ADD && stage == 3)
|
||||||
|
ctrl_ro <= 1;
|
||||||
|
else if (ir[7:4] == OP_SUB && stage == 3)
|
||||||
|
ctrl_ro <= 1;
|
||||||
|
else
|
||||||
|
ctrl_ro <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
// Instruction Register Out
|
||||||
|
reg ctrl_io;
|
||||||
|
always @(negedge clk) begin
|
||||||
|
if (ir[7:4] == OP_LDA && stage == 2)
|
||||||
|
ctrl_io <= 1;
|
||||||
|
else if (ir[7:4] == OP_LDI && stage == 2)
|
||||||
|
ctrl_io <= 1;
|
||||||
|
else if (ir[7:4] == OP_ADD && stage == 2)
|
||||||
|
ctrl_io <= 1;
|
||||||
|
else if (ir[7:4] == OP_SUB && stage == 2)
|
||||||
|
ctrl_io <= 1;
|
||||||
|
else if (ir[7:4] == OP_STA && stage == 2)
|
||||||
|
ctrl_io <= 1;
|
||||||
|
else if (ir[7:4] == OP_JMP && stage == 2)
|
||||||
|
ctrl_io <= 1;
|
||||||
|
else if (ir[7:4] == OP_JC && stage == 2)
|
||||||
|
ctrl_io <= 1;
|
||||||
|
else if (ir[7:4] == OP_JZ && stage == 2)
|
||||||
|
ctrl_io <= 1;
|
||||||
|
else
|
||||||
|
ctrl_io <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
// Instruction Register In
|
||||||
|
reg ctrl_ii;
|
||||||
|
always @(negedge clk) begin
|
||||||
|
if (stage == 1)
|
||||||
|
ctrl_ii <= 1;
|
||||||
|
else
|
||||||
|
ctrl_ii <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
// A Register In
|
||||||
|
reg ctrl_ai;
|
||||||
|
always @(negedge clk) begin
|
||||||
|
if (ir[7:4] == OP_LDI && stage == 2)
|
||||||
|
ctrl_ai <= 1;
|
||||||
|
else if (ir[7:4] == OP_LDA && stage == 3)
|
||||||
|
ctrl_ai <= 1;
|
||||||
|
else if (ir[7:4] == OP_ADD && stage == 4)
|
||||||
|
ctrl_ai <= 1;
|
||||||
|
else if (ir[7:4] == OP_SUB && stage == 4)
|
||||||
|
ctrl_ai <= 1;
|
||||||
|
else
|
||||||
|
ctrl_ai <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
// A Register Out
|
||||||
|
reg ctrl_ao;
|
||||||
|
always @(negedge clk) begin
|
||||||
|
if (ir[7:4] == OP_STA && stage == 3)
|
||||||
|
ctrl_ao <= 1;
|
||||||
|
else if (ir[7:4] == OP_OUT && stage == 2)
|
||||||
|
ctrl_ao <= 1;
|
||||||
|
else
|
||||||
|
ctrl_ao <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
// Sum Out
|
||||||
|
reg ctrl_eo;
|
||||||
|
always @(negedge clk) begin
|
||||||
|
if (ir[7:4] == OP_ADD && stage == 4)
|
||||||
|
ctrl_eo <= 1;
|
||||||
|
else if (ir[7:4] == OP_SUB && stage == 4)
|
||||||
|
ctrl_eo <= 1;
|
||||||
|
else
|
||||||
|
ctrl_eo <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
// Subtract
|
||||||
|
reg ctrl_su;
|
||||||
|
always @(negedge clk) begin
|
||||||
|
if (ir[7:4] == OP_SUB && stage == 4)
|
||||||
|
ctrl_su <= 1;
|
||||||
|
else
|
||||||
|
ctrl_su <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
// B Register In
|
||||||
|
reg ctrl_bi;
|
||||||
|
always @(negedge clk) begin
|
||||||
|
if (ir[7:4] == OP_ADD && stage == 3)
|
||||||
|
ctrl_bi <= 1;
|
||||||
|
else if (ir[7:4] == OP_SUB && stage == 3)
|
||||||
|
ctrl_bi <= 1;
|
||||||
|
else
|
||||||
|
ctrl_bi <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
// Output Register In
|
||||||
|
reg ctrl_oi;
|
||||||
|
always @(negedge clk) begin
|
||||||
|
if (ir[7:4] == OP_OUT && stage == 2)
|
||||||
|
ctrl_oi <= 1;
|
||||||
|
else
|
||||||
|
ctrl_oi <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
// Counter Enable
|
||||||
|
reg ctrl_ce;
|
||||||
|
always @(negedge clk) begin
|
||||||
|
if (stage == 1)
|
||||||
|
ctrl_ce <= 1;
|
||||||
|
else
|
||||||
|
ctrl_ce <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
// Counter Out
|
||||||
|
reg ctrl_co;
|
||||||
|
always @(negedge clk) begin
|
||||||
|
// Always in Stage 0
|
||||||
|
if (stage == 0)
|
||||||
|
ctrl_co <= 1;
|
||||||
|
else
|
||||||
|
ctrl_co <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
// Jump
|
||||||
|
reg ctrl_jp;
|
||||||
|
always @(negedge clk) begin
|
||||||
|
if (ir[7:4] == OP_JMP && stage == 2)
|
||||||
|
ctrl_jp <= 1;
|
||||||
|
else if (ir[7:4] == OP_JC && stage == 2 && flags[FLAG_C] == 1)
|
||||||
|
ctrl_jp <= 1;
|
||||||
|
else if (ir[7:4] == OP_JZ && stage == 2 && flags[FLAG_Z] == 1)
|
||||||
|
ctrl_jp <= 1;
|
||||||
|
else
|
||||||
|
ctrl_jp <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
// Flags Register In
|
||||||
|
reg ctrl_fi;
|
||||||
|
always @(negedge clk) begin
|
||||||
|
if (ir[7:4] == OP_ADD && stage == 4)
|
||||||
|
ctrl_fi <= 1;
|
||||||
|
else if (ir[7:4] == OP_SUB && stage == 4)
|
||||||
|
ctrl_fi <= 1;
|
||||||
|
else
|
||||||
|
ctrl_fi <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Bus
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
wire[7:0] bus;
|
||||||
|
assign bus =
|
||||||
|
ctrl_co ? pc :
|
||||||
|
ctrl_ro ? mem[mar] :
|
||||||
|
ctrl_io ? ir[3:0] :
|
||||||
|
ctrl_ao ? a_reg :
|
||||||
|
ctrl_eo ? alu :
|
||||||
|
8'b0;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Program Counter
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
reg[3:0] pc;
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset)
|
||||||
|
pc <= 0;
|
||||||
|
else if (ctrl_ce)
|
||||||
|
pc <= pc + 1;
|
||||||
|
else if (ctrl_jp)
|
||||||
|
pc <= bus[3:0];
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Instruction Step Counter
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
reg[2:0] stage;
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset)
|
||||||
|
stage <= 0;
|
||||||
|
else if (stage == 5 || ctrl_jp)
|
||||||
|
stage <= 0;
|
||||||
|
else if (ctrl_ht || stage == 6)
|
||||||
|
// For a halt, put it into a stage it can never get out of
|
||||||
|
stage <= 6;
|
||||||
|
else
|
||||||
|
stage <= stage + 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Memory Address Register
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
reg[3:0] mar;
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset)
|
||||||
|
mar <= 0;
|
||||||
|
else if (ctrl_mi)
|
||||||
|
mar <= bus[3:0];
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Memory
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
reg[7:0] mem[16];
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (ctrl_ri)
|
||||||
|
mem[mar] <= bus;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Instruction Register
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
reg[7:0] ir;
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset)
|
||||||
|
ir <= 0;
|
||||||
|
else if (ctrl_ii)
|
||||||
|
ir <= bus;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// ALU
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
reg[7:0] a_reg;
|
||||||
|
reg[7:0] b_reg;
|
||||||
|
wire[7:0] b_reg_out;
|
||||||
|
wire[8:0] alu;
|
||||||
|
wire flag_z, flag_c;
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset)
|
||||||
|
a_reg <= 0;
|
||||||
|
else if (ctrl_ai)
|
||||||
|
a_reg <= bus;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset)
|
||||||
|
b_reg <= 0;
|
||||||
|
else if (ctrl_bi)
|
||||||
|
b_reg <= bus;
|
||||||
|
end
|
||||||
|
|
||||||
|
// Zero flag is set if ALU is zero
|
||||||
|
assign flag_z = (alu[7:0] == 0) ? 1 : 0;
|
||||||
|
|
||||||
|
// Use twos-complement for subtraction
|
||||||
|
assign b_reg_out = ctrl_su ? ~b_reg + 1 : b_reg;
|
||||||
|
|
||||||
|
// Carry flag is set if there's an overflow into bit 8 of the ALU
|
||||||
|
assign flag_c = alu[8];
|
||||||
|
|
||||||
|
assign alu = a_reg + b_reg_out;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Flags Register
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
parameter FLAG_C = 1;
|
||||||
|
parameter FLAG_Z = 0;
|
||||||
|
|
||||||
|
reg[1:0] flags;
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset)
|
||||||
|
flags <= 0;
|
||||||
|
else if (ctrl_fi)
|
||||||
|
flags <= {flag_c, flag_z};
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Output Register
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset)
|
||||||
|
out <= 0;
|
||||||
|
else if (ctrl_oi)
|
||||||
|
out <= bus;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Program to Run
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
mem[0] = {OP_OUT, 4'b0};
|
||||||
|
mem[1] = {OP_ADD, 4'hF};
|
||||||
|
mem[2] = {OP_JC, 4'h4};
|
||||||
|
mem[3] = {OP_JMP, 4'h0};
|
||||||
|
mem[4] = {OP_SUB, 4'hF};
|
||||||
|
mem[5] = {OP_OUT, 4'h0};
|
||||||
|
mem[6] = {OP_JZ, 4'h0};
|
||||||
|
mem[7] = {OP_JMP, 4'h4};
|
||||||
|
mem[8] = {OP_NOP, 4'h0};
|
||||||
|
mem[9] = {OP_NOP, 4'h0};
|
||||||
|
mem[10] = {OP_NOP, 4'h0};
|
||||||
|
mem[11] = {OP_NOP, 4'h0};
|
||||||
|
mem[12] = {OP_NOP, 4'h0};
|
||||||
|
mem[13] = {OP_NOP, 4'h0};
|
||||||
|
mem[14] = {OP_NOP, 4'h0};
|
||||||
|
mem[15] = {8'h01}; // DATA = 1
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
###############################################################################
|
||||||
|
#
|
||||||
|
# TinyFPGA BX constraint file (.pcf)
|
||||||
|
#
|
||||||
|
###############################################################################
|
||||||
|
#
|
||||||
|
# Copyright (c) 2018, Luke Valenty
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are met:
|
||||||
|
#
|
||||||
|
# 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
# list of conditions and the following disclaimer.
|
||||||
|
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
# this list of conditions and the following disclaimer in the documentation
|
||||||
|
# and/or other materials provided with the distribution.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#
|
||||||
|
# The views and conclusions contained in the software and documentation are those
|
||||||
|
# of the authors and should not be interpreted as representing official policies,
|
||||||
|
# either expressed or implied, of the <project name> project.
|
||||||
|
#
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
####
|
||||||
|
# TinyFPGA BX information: https://github.com/tinyfpga/TinyFPGA-BX/
|
||||||
|
####
|
||||||
|
|
||||||
|
# Left side of board
|
||||||
|
set_io --warn-no-port PIN_1 A2
|
||||||
|
set_io --warn-no-port PIN_2 A1
|
||||||
|
set_io --warn-no-port PIN_3 B1
|
||||||
|
set_io --warn-no-port PIN_4 C2
|
||||||
|
set_io --warn-no-port PIN_5 C1
|
||||||
|
set_io --warn-no-port PIN_6 D2
|
||||||
|
set_io --warn-no-port PIN_7 D1
|
||||||
|
set_io --warn-no-port PIN_8 E2
|
||||||
|
set_io --warn-no-port PIN_9 E1
|
||||||
|
set_io --warn-no-port PIN_10 G2
|
||||||
|
set_io --warn-no-port PIN_11 H1
|
||||||
|
set_io --warn-no-port PIN_12 J1
|
||||||
|
set_io --warn-no-port PIN_13 H2
|
||||||
|
|
||||||
|
# Right side of board
|
||||||
|
set_io --warn-no-port PIN_14 H9
|
||||||
|
set_io --warn-no-port PIN_15 D9
|
||||||
|
set_io --warn-no-port PIN_16 D8
|
||||||
|
set_io --warn-no-port PIN_17 C9
|
||||||
|
set_io --warn-no-port PIN_18 A9
|
||||||
|
set_io --warn-no-port PIN_19 B8
|
||||||
|
set_io --warn-no-port PIN_20 A8
|
||||||
|
set_io --warn-no-port PIN_21 B7
|
||||||
|
set_io --warn-no-port PIN_22 A7
|
||||||
|
set_io --warn-no-port PIN_23 B6
|
||||||
|
set_io --warn-no-port PIN_24 A6
|
||||||
|
|
||||||
|
# SPI flash interface on bottom of board
|
||||||
|
set_io --warn-no-port SPI_SS F7
|
||||||
|
set_io --warn-no-port SPI_SCK G7
|
||||||
|
set_io --warn-no-port SPI_IO0 G6
|
||||||
|
set_io --warn-no-port SPI_IO1 H7
|
||||||
|
set_io --warn-no-port SPI_IO2 H4
|
||||||
|
set_io --warn-no-port SPI_IO3 J8
|
||||||
|
|
||||||
|
# General purpose pins on bottom of board
|
||||||
|
set_io --warn-no-port PIN_25 G1
|
||||||
|
set_io --warn-no-port PIN_26 J3
|
||||||
|
set_io --warn-no-port PIN_27 J4
|
||||||
|
set_io --warn-no-port PIN_28 G9
|
||||||
|
set_io --warn-no-port PIN_29 J9
|
||||||
|
set_io --warn-no-port PIN_30 E8
|
||||||
|
set_io --warn-no-port PIN_31 J2
|
||||||
|
|
||||||
|
# LED
|
||||||
|
set_io --warn-no-port LED B3
|
||||||
|
|
||||||
|
# USB
|
||||||
|
set_io --warn-no-port USBP B4
|
||||||
|
set_io --warn-no-port USBN A4
|
||||||
|
set_io --warn-no-port USBPU A3
|
||||||
|
|
||||||
|
# 16MHz clock
|
||||||
|
set_io --warn-no-port CLK B2 # input
|
|
@ -0,0 +1,67 @@
|
||||||
|
`include "cpu.v"
|
||||||
|
`include "7seg.v"
|
||||||
|
`include "bin_to_bcd.v"
|
||||||
|
|
||||||
|
module top(
|
||||||
|
input CLK,
|
||||||
|
input PIN_13,
|
||||||
|
output PIN_9,
|
||||||
|
output PIN_10, output PIN_11,
|
||||||
|
output PIN_12, output PIN_14,
|
||||||
|
output PIN_15, output PIN_16,
|
||||||
|
output PIN_17, output PIN_18,
|
||||||
|
output PIN_19, output PIN_20);
|
||||||
|
|
||||||
|
reg[7:0] out;
|
||||||
|
reg[23:0] clk;
|
||||||
|
always @(posedge CLK)
|
||||||
|
clk <= clk + 1;
|
||||||
|
|
||||||
|
cpu cpu0(
|
||||||
|
.clk(clk[15]),
|
||||||
|
.reset(PIN_13),
|
||||||
|
.out(out));
|
||||||
|
|
||||||
|
reg[3:0] cathode = 4'b1110;
|
||||||
|
reg[6:0] seg_ones;
|
||||||
|
reg[6:0] seg_tens;
|
||||||
|
reg[6:0] seg_hundreds;
|
||||||
|
wire[11:0] bcd;
|
||||||
|
|
||||||
|
bin_to_bcd bin_to_bcd0(out, bcd);
|
||||||
|
|
||||||
|
seven_seg seven_seg_ones(
|
||||||
|
.bcd(bcd[3:0]),
|
||||||
|
.segments(seg_ones));
|
||||||
|
|
||||||
|
seven_seg seven_seg_tens(
|
||||||
|
.bcd(bcd[7:4]),
|
||||||
|
.segments(seg_tens));
|
||||||
|
|
||||||
|
seven_seg seven_seg_hundreds(
|
||||||
|
.bcd(bcd[11:8]),
|
||||||
|
.segments(seg_hundreds));
|
||||||
|
|
||||||
|
always @(posedge clk[10])
|
||||||
|
case (cathode)
|
||||||
|
4'b1110: begin
|
||||||
|
cathode = 4'b1011;
|
||||||
|
{PIN_11, PIN_9, PIN_15, PIN_18, PIN_19, PIN_10, PIN_14} = seg_hundreds;
|
||||||
|
end
|
||||||
|
4'b1011: begin
|
||||||
|
cathode = 4'b1101;
|
||||||
|
{PIN_11, PIN_9, PIN_15, PIN_18, PIN_19, PIN_10, PIN_14} = seg_tens;
|
||||||
|
end
|
||||||
|
4'b1101: begin
|
||||||
|
cathode = 4'b1110;
|
||||||
|
{PIN_11, PIN_9, PIN_15, PIN_18, PIN_19, PIN_10, PIN_14} = seg_ones;
|
||||||
|
end
|
||||||
|
default: begin
|
||||||
|
cathode = 4'b1111;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
|
||||||
|
assign {PIN_20, PIN_17, PIN_16, PIN_12} = cathode;
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
Loading…
Reference in New Issue