diff options
Diffstat (limited to 'sim')
| -rw-r--r-- | sim/.gitignore | 2 | ||||
| -rw-r--r-- | sim/Makefile | 12 | ||||
| -rw-r--r-- | sim/alu.sv | 76 | ||||
| -rw-r--r-- | sim/control.sv | 54 | ||||
| -rw-r--r-- | sim/decode.sv | 82 | ||||
| -rw-r--r-- | sim/main.cpp | 61 | ||||
| -rw-r--r-- | sim/memory.sv | 35 | ||||
| -rw-r--r-- | sim/pc.sv | 36 | ||||
| -rw-r--r-- | sim/rf.sv | 39 | ||||
| -rw-r--r-- | sim/tmp.sv | 41 | ||||
| -rw-r--r-- | sim/top.sv | 27 | ||||
| -rw-r--r-- | sim/uart.sv | 47 | ||||
| -rw-r--r-- | sim/urom.sv | 19 |
13 files changed, 531 insertions, 0 deletions
diff --git a/sim/.gitignore b/sim/.gitignore new file mode 100644 index 0000000..dc3fae8 --- /dev/null +++ b/sim/.gitignore | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | /build | ||
| 2 | /verilator | ||
diff --git a/sim/Makefile b/sim/Makefile new file mode 100644 index 0000000..af9d22a --- /dev/null +++ b/sim/Makefile | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | run: build/Vtop | ||
| 2 | $< | ||
| 3 | .PHONY: run | ||
| 4 | |||
| 5 | build/Vtop: $(wildcard *.cpp *.sv) | ||
| 6 | @rm -rf verilator | ||
| 7 | @mkdir -p build verilator | ||
| 8 | verilator +1800-2017ext+sv -Wall -Wno-BLKSEQ -Wno-UNUSED -O3 -Ihdl --Mdir verilator --trace --cc --build -j --exe --top-module top $(wildcard *.cpp *.sv) | ||
| 9 | @ln -t build -f verilator/Vtop | ||
| 10 | @rm -rf verilator | ||
| 11 | |||
| 12 | .SECONDARY: | ||
diff --git a/sim/alu.sv b/sim/alu.sv new file mode 100644 index 0000000..407b083 --- /dev/null +++ b/sim/alu.sv | |||
| @@ -0,0 +1,76 @@ | |||
| 1 | module alu | ||
| 2 | #( parameter UROM = "<no file specified>" | ||
| 3 | , parameter UIP_BITS = 15 | ||
| 4 | , parameter UROM_BITS = 8 | ||
| 5 | , parameter BUS_BITS = 16 | ||
| 6 | ) | ||
| 7 | ( input bit clk | ||
| 8 | , input bit reset | ||
| 9 | , input bit [UIP_BITS-1:0] uip | ||
| 10 | , inout bit [BUS_BITS-1:0] abus | ||
| 11 | , inout bit [BUS_BITS-1:0] dbus | ||
| 12 | ); | ||
| 13 | |||
| 14 | bit [BUS_BITS-1:0] x; | ||
| 15 | |||
| 16 | typedef enum | ||
| 17 | { OP | ||
| 18 | , OP_SEL0 | ||
| 19 | , OP_SEL1 | ||
| 20 | , OP_SEL2 | ||
| 21 | , OUTADDR | ||
| 22 | , OUTDATA | ||
| 23 | } CtrlBit; | ||
| 24 | |||
| 25 | bit [UROM_BITS-1:0] ctrl; | ||
| 26 | urom#(UROM, UIP_BITS, UROM_BITS) urom(uip, ctrl); | ||
| 27 | |||
| 28 | bit [2:0] sel; | ||
| 29 | assign sel = {ctrl[OP_SEL2], ctrl[OP_SEL1], ctrl[OP_SEL0]}; | ||
| 30 | |||
| 31 | bit [BUS_BITS-1:0] and_result; | ||
| 32 | bit [BUS_BITS-1:0] or_result; | ||
| 33 | bit [BUS_BITS-1:0] xor_result; | ||
| 34 | bit [BUS_BITS-1:0] add_result; | ||
| 35 | bit [BUS_BITS-1:0] sub_result; | ||
| 36 | bit [BUS_BITS-1:0] cmp_result; | ||
| 37 | bit [BUS_BITS-1:0] lshift_result; | ||
| 38 | bit [BUS_BITS-1:0] rshift_result; | ||
| 39 | |||
| 40 | assign and_result = abus & dbus; | ||
| 41 | assign or_result = abus | dbus; | ||
| 42 | assign xor_result = abus ^ dbus; | ||
| 43 | assign add_result = abus + dbus; | ||
| 44 | assign sub_result = abus - dbus; | ||
| 45 | assign cmp_result = {{(BUS_BITS-6){1'b0}}, | ||
| 46 | (abus != 0) & (dbus != 0), | ||
| 47 | (abus != 0) | (dbus != 0), | ||
| 48 | (abus != 0) ^ (dbus != 0), | ||
| 49 | abus > dbus, | ||
| 50 | abus == dbus, | ||
| 51 | abus < dbus}; | ||
| 52 | assign lshift_result = (dbus >= BUS_BITS) ? 0 : (abus << dbus); | ||
| 53 | assign rshift_result = (dbus >= BUS_BITS) ? 0 : (abus >> dbus); | ||
| 54 | |||
| 55 | bit [BUS_BITS-1:0] newx; | ||
| 56 | assign newx = | ||
| 57 | (sel == 0) ? and_result : | ||
| 58 | (sel == 1) ? or_result : | ||
| 59 | (sel == 2) ? xor_result : | ||
| 60 | (sel == 3) ? add_result : | ||
| 61 | (sel == 4) ? sub_result : | ||
| 62 | (sel == 5) ? cmp_result : | ||
| 63 | (sel == 6) ? lshift_result : | ||
| 64 | (sel == 7) ? rshift_result : | ||
| 65 | {(BUS_BITS){1'bX}}; | ||
| 66 | |||
| 67 | assign abus = ctrl[OUTADDR] ? x : {(BUS_BITS){1'bZ}}; | ||
| 68 | assign dbus = ctrl[OUTDATA] ? x : {(BUS_BITS){1'bZ}}; | ||
| 69 | |||
| 70 | always @(posedge clk) begin | ||
| 71 | if (ctrl[OP]) begin | ||
| 72 | x <= newx; | ||
| 73 | end | ||
| 74 | end | ||
| 75 | |||
| 76 | endmodule | ||
diff --git a/sim/control.sv b/sim/control.sv new file mode 100644 index 0000000..7808f61 --- /dev/null +++ b/sim/control.sv | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | module control | ||
| 2 | #( parameter UROM = "<no file specified>" | ||
| 3 | , parameter UIP_BITS = 15 | ||
| 4 | , parameter UROM_BITS = 8 | ||
| 5 | , parameter BUS_BITS = 16 | ||
| 6 | , parameter CONST_0 = "<no file specified>" | ||
| 7 | , parameter CONST_1 = "<no file specified>" | ||
| 8 | , parameter RESET = ~0 | ||
| 9 | ) | ||
| 10 | ( input bit clk | ||
| 11 | , input bit reset | ||
| 12 | , output bit [UIP_BITS-1:0] uip | ||
| 13 | , inout bit [BUS_BITS-1:0] abus | ||
| 14 | , inout bit [BUS_BITS-1:0] dbus | ||
| 15 | ); | ||
| 16 | |||
| 17 | typedef enum | ||
| 18 | { HALT | ||
| 19 | , SET_UIP_COND | ||
| 20 | , NOCOND | ||
| 21 | , OUTADDR | ||
| 22 | , OUTDATA | ||
| 23 | } CtrlBit; | ||
| 24 | |||
| 25 | bit [UROM_BITS-1:0] ctrl; | ||
| 26 | urom#(UROM, UIP_BITS, UROM_BITS) urom(uip, ctrl); | ||
| 27 | |||
| 28 | bit [UROM_BITS*2-1:0] constant; | ||
| 29 | urom#(CONST_0, UIP_BITS, UROM_BITS) const_0(uip, constant[1*UROM_BITS-1:0*UROM_BITS]); | ||
| 30 | urom#(CONST_1, UIP_BITS, UROM_BITS) const_1(uip, constant[2*UROM_BITS-1:1*UROM_BITS]); | ||
| 31 | |||
| 32 | assign abus = ctrl[OUTADDR] ? constant : {(BUS_BITS){1'bZ}}; | ||
| 33 | assign dbus = ctrl[OUTDATA] ? constant : {(BUS_BITS){1'bZ}}; | ||
| 34 | |||
| 35 | bit cond; | ||
| 36 | assign cond = (dbus != 0) || ctrl[NOCOND]; | ||
| 37 | |||
| 38 | always @(posedge clk) begin | ||
| 39 | if (reset) begin | ||
| 40 | uip <= RESET; | ||
| 41 | end else begin | ||
| 42 | if (! ctrl[HALT]) begin | ||
| 43 | if (ctrl[SET_UIP_COND] && cond) begin | ||
| 44 | uip <= abus[UIP_BITS-1:0]; | ||
| 45 | end else begin | ||
| 46 | uip <= uip + 1; | ||
| 47 | end | ||
| 48 | end else begin | ||
| 49 | $finish; | ||
| 50 | end | ||
| 51 | end | ||
| 52 | end | ||
| 53 | |||
| 54 | endmodule | ||
diff --git a/sim/decode.sv b/sim/decode.sv new file mode 100644 index 0000000..5c9a9c9 --- /dev/null +++ b/sim/decode.sv | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | module decode | ||
| 2 | #( parameter UROM = "<no file specified>" | ||
| 3 | , parameter UIP_BITS = 15 | ||
| 4 | , parameter UROM_BITS = 8 | ||
| 5 | , parameter BUS_BITS = 16 | ||
| 6 | , parameter OPCODE_BITS = 8 | ||
| 7 | ) | ||
| 8 | ( input bit clk | ||
| 9 | , input bit reset | ||
| 10 | , input bit [UIP_BITS-1:0] uip | ||
| 11 | , inout bit [BUS_BITS-1:0] abus | ||
| 12 | , inout bit [BUS_BITS-1:0] dbus | ||
| 13 | ); | ||
| 14 | |||
| 15 | bit [OPCODE_BITS-1:0] opcode; | ||
| 16 | bit [BUS_BITS-1:0] a; | ||
| 17 | bit [BUS_BITS-1:0] b; | ||
| 18 | bit needmore; | ||
| 19 | |||
| 20 | bit [UIP_BITS-1:0] new_uip; | ||
| 21 | assign new_uip = {opcode, {(UIP_BITS-OPCODE_BITS){1'b0}}}; | ||
| 22 | |||
| 23 | typedef enum | ||
| 24 | { CLEAR | ||
| 25 | , DECODE | ||
| 26 | , OUTADDR | ||
| 27 | , OUTADDR_SEL0 | ||
| 28 | , OUTADDR_SEL1 | ||
| 29 | , OUTDATA | ||
| 30 | , OUTDATA_SEL0 | ||
| 31 | , OUTDATA_SEL1 | ||
| 32 | } CtrlBit; | ||
| 33 | |||
| 34 | bit [UROM_BITS-1:0] ctrl; | ||
| 35 | urom#(UROM, UIP_BITS, UROM_BITS) urom(uip, ctrl); | ||
| 36 | |||
| 37 | bit [1:0] asel; | ||
| 38 | assign asel = {ctrl[OUTADDR_SEL1], ctrl[OUTADDR_SEL0]}; | ||
| 39 | |||
| 40 | bit [1:0] dsel; | ||
| 41 | assign dsel = {ctrl[OUTDATA_SEL1], ctrl[OUTDATA_SEL0]}; | ||
| 42 | |||
| 43 | bit [BUS_BITS-1:0] aout; | ||
| 44 | assign aout = | ||
| 45 | (asel == 0) ? a : | ||
| 46 | (asel == 1) ? b : | ||
| 47 | (asel == 2) ? {{(BUS_BITS-UIP_BITS){1'b0}}, new_uip} : | ||
| 48 | {(BUS_BITS){1'bX}}; | ||
| 49 | |||
| 50 | assign abus = ctrl[OUTADDR] ? aout : {(BUS_BITS){1'bZ}}; | ||
| 51 | |||
| 52 | bit [BUS_BITS-1:0] dout; | ||
| 53 | assign dout = | ||
| 54 | (dsel == 0) ? a : | ||
| 55 | (dsel == 1) ? b : | ||
| 56 | (dsel == 2) ? {{(BUS_BITS-1){1'b0}}, needmore} : | ||
| 57 | {(BUS_BITS){1'bX}}; | ||
| 58 | |||
| 59 | assign dbus = ctrl[OUTDATA] ? dout : {(BUS_BITS){1'bZ}}; | ||
| 60 | |||
| 61 | always @(posedge clk) begin | ||
| 62 | if (reset || ctrl[CLEAR]) begin | ||
| 63 | opcode <= 0; | ||
| 64 | a <= 0; | ||
| 65 | b <= 0; | ||
| 66 | needmore <= 1; | ||
| 67 | end else if (ctrl[DECODE]) begin | ||
| 68 | automatic bit m = dbus[7]; | ||
| 69 | automatic bit i = dbus[6]; | ||
| 70 | automatic bit [1:0] field = dbus[5:4]; | ||
| 71 | automatic bit [3:0] shift = dbus[3:0]; | ||
| 72 | needmore <= m; | ||
| 73 | if (field == 0) begin | ||
| 74 | opcode <= {i ? ~opcode[OPCODE_BITS-1-4:0] : opcode[OPCODE_BITS-1-4:0], shift}; | ||
| 75 | end else if (field == 2) begin | ||
| 76 | a <= {i ? ~a[BUS_BITS-1-4:0] : a[BUS_BITS-1-4:0], shift}; | ||
| 77 | end else if (field == 3) begin | ||
| 78 | b <= {i ? ~b[BUS_BITS-1-4:0] : b[BUS_BITS-1-4:0], shift}; | ||
| 79 | end | ||
| 80 | end | ||
| 81 | end | ||
| 82 | endmodule | ||
diff --git a/sim/main.cpp b/sim/main.cpp new file mode 100644 index 0000000..ac4befa --- /dev/null +++ b/sim/main.cpp | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | #include <cstdint> | ||
| 2 | #include <iostream> | ||
| 3 | #include <verilated.h> | ||
| 4 | #include <verilated_vcd_c.h> | ||
| 5 | |||
| 6 | #include "Vtop.h" | ||
| 7 | |||
| 8 | std::uint64_t phases = 0; | ||
| 9 | |||
| 10 | double sc_time_stamp() | ||
| 11 | { | ||
| 12 | return (double)phases / 2; | ||
| 13 | } | ||
| 14 | |||
| 15 | int main(int argc, const char *argv[]) | ||
| 16 | { | ||
| 17 | Verilated::commandArgs(argc, argv); | ||
| 18 | |||
| 19 | Verilated::traceEverOn(true); | ||
| 20 | VerilatedVcdC vcd; | ||
| 21 | |||
| 22 | Vtop top; | ||
| 23 | top.trace(&vcd, 100 /* levels of hierarchy */); | ||
| 24 | |||
| 25 | vcd.set_time_unit("ns"); | ||
| 26 | vcd.set_time_resolution("ns"); | ||
| 27 | vcd.open("build/out.vcd"); | ||
| 28 | |||
| 29 | std::cout << "*** RESET SEQUENCE ***\n"; | ||
| 30 | |||
| 31 | top.clk = 0; | ||
| 32 | top.reset = 1; | ||
| 33 | top.eval(); | ||
| 34 | vcd.dump(++phases); | ||
| 35 | |||
| 36 | top.clk = 1; | ||
| 37 | top.eval(); | ||
| 38 | vcd.dump(++phases); | ||
| 39 | |||
| 40 | top.clk = 0; | ||
| 41 | top.reset = 0; | ||
| 42 | top.eval(); | ||
| 43 | vcd.dump(++phases); | ||
| 44 | |||
| 45 | std::cout << "*** MAIN LOOP ***\n"; | ||
| 46 | |||
| 47 | for (unsigned int i = 0; i < 10000 && !Verilated::gotFinish(); ++i) { | ||
| 48 | top.clk = 1; | ||
| 49 | top.eval(); | ||
| 50 | vcd.dump(++phases); | ||
| 51 | top.clk = 0; | ||
| 52 | top.eval(); | ||
| 53 | vcd.dump(++phases); | ||
| 54 | } | ||
| 55 | |||
| 56 | std::cout << "\n"; | ||
| 57 | |||
| 58 | vcd.close(); | ||
| 59 | |||
| 60 | return 0; | ||
| 61 | } | ||
diff --git a/sim/memory.sv b/sim/memory.sv new file mode 100644 index 0000000..0eb1233 --- /dev/null +++ b/sim/memory.sv | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | module memory | ||
| 2 | #( parameter UROM = "<no file specified>" | ||
| 3 | , parameter UIP_BITS = 15 | ||
| 4 | , parameter UROM_BITS = 8 | ||
| 5 | , parameter BUS_BITS = 16 | ||
| 6 | , parameter IMAGE = "<no file specified>" | ||
| 7 | , parameter BYTE_BITS = 8 | ||
| 8 | ) | ||
| 9 | ( input bit clk | ||
| 10 | , input bit reset | ||
| 11 | , input bit [UIP_BITS-1:0] uip | ||
| 12 | , inout bit [BUS_BITS-1:0] abus | ||
| 13 | , inout bit [BUS_BITS-1:0] dbus | ||
| 14 | ); | ||
| 15 | |||
| 16 | bit [BYTE_BITS-1:0] storage [0:(1<<BUS_BITS)-1]; | ||
| 17 | initial $readmemh(IMAGE, storage); | ||
| 18 | |||
| 19 | typedef enum | ||
| 20 | { STORE | ||
| 21 | , OUTDATA | ||
| 22 | } CtrlBit; | ||
| 23 | |||
| 24 | bit [UROM_BITS-1:0] ctrl; | ||
| 25 | urom#(UROM, UIP_BITS, UROM_BITS) urom(uip, ctrl); | ||
| 26 | |||
| 27 | assign dbus = ctrl[OUTDATA] ? {{(BUS_BITS-BYTE_BITS){1'b0}}, storage[abus]} : {(BUS_BITS){1'bZ}}; | ||
| 28 | |||
| 29 | always @(posedge clk) begin | ||
| 30 | if (ctrl[STORE]) begin | ||
| 31 | storage[abus] <= dbus[BYTE_BITS-1:0]; | ||
| 32 | end | ||
| 33 | end | ||
| 34 | |||
| 35 | endmodule | ||
diff --git a/sim/pc.sv b/sim/pc.sv new file mode 100644 index 0000000..1a3aaee --- /dev/null +++ b/sim/pc.sv | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | module pc | ||
| 2 | #( parameter UROM = "<no file specified>" | ||
| 3 | , parameter UIP_BITS = 15 | ||
| 4 | , parameter UROM_BITS = 8 | ||
| 5 | , parameter BUS_BITS = 16 | ||
| 6 | , parameter RESET = 0 | ||
| 7 | ) | ||
| 8 | ( input bit clk | ||
| 9 | , input bit reset | ||
| 10 | , input bit [UIP_BITS-1:0] uip | ||
| 11 | , inout bit [BUS_BITS-1:0] abus | ||
| 12 | , inout bit [BUS_BITS-1:0] dbus | ||
| 13 | ); | ||
| 14 | |||
| 15 | bit [BUS_BITS-1:0] addr; | ||
| 16 | |||
| 17 | typedef enum | ||
| 18 | { LOAD | ||
| 19 | , INCREMENT | ||
| 20 | , OUTADDR | ||
| 21 | } CtrlBit; | ||
| 22 | |||
| 23 | bit [UROM_BITS-1:0] ctrl; | ||
| 24 | urom#(UROM, UIP_BITS, UROM_BITS) urom(uip, ctrl); | ||
| 25 | |||
| 26 | assign abus = ctrl[OUTADDR] ? addr : {(BUS_BITS){1'bZ}}; | ||
| 27 | |||
| 28 | always @(posedge clk) begin | ||
| 29 | if (reset) begin | ||
| 30 | addr <= RESET; | ||
| 31 | end else begin | ||
| 32 | addr <= (ctrl[LOAD] ? abus : addr) + (ctrl[INCREMENT] ? 1 : 0); | ||
| 33 | end | ||
| 34 | end | ||
| 35 | |||
| 36 | endmodule | ||
diff --git a/sim/rf.sv b/sim/rf.sv new file mode 100644 index 0000000..37502ce --- /dev/null +++ b/sim/rf.sv | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | module rf | ||
| 2 | #( parameter UROM = "<no file specified>" | ||
| 3 | , parameter UIP_BITS = 15 | ||
| 4 | , parameter UROM_BITS = 8 | ||
| 5 | , parameter BUS_BITS = 16 | ||
| 6 | , parameter NAME_BITS = 3 | ||
| 7 | ) | ||
| 8 | ( input bit clk | ||
| 9 | , input bit reset | ||
| 10 | , input bit [UIP_BITS-1:0] uip | ||
| 11 | , inout bit [BUS_BITS-1:0] abus | ||
| 12 | , inout bit [BUS_BITS-1:0] dbus | ||
| 13 | ); | ||
| 14 | |||
| 15 | bit [BUS_BITS-1:0] storage [0:(1<<NAME_BITS)-1]; | ||
| 16 | |||
| 17 | typedef enum | ||
| 18 | { STORE | ||
| 19 | , RESET | ||
| 20 | , OUTDATA | ||
| 21 | } CtrlBit; | ||
| 22 | |||
| 23 | bit [UROM_BITS-1:0] ctrl; | ||
| 24 | urom#(UROM, UIP_BITS, UROM_BITS) urom(uip, ctrl); | ||
| 25 | |||
| 26 | assign dbus = ctrl[OUTDATA] ? storage[abus[NAME_BITS-1:0]] : {(BUS_BITS){1'bZ}}; | ||
| 27 | |||
| 28 | always @(posedge clk) begin | ||
| 29 | if (reset || ctrl[RESET]) begin | ||
| 30 | for (int i = 0; i < (1 << NAME_BITS); ++i) | ||
| 31 | storage[i] <= 0; | ||
| 32 | end else begin | ||
| 33 | if (ctrl[STORE]) begin | ||
| 34 | storage[abus[NAME_BITS-1:0]] <= dbus; | ||
| 35 | end | ||
| 36 | end | ||
| 37 | end | ||
| 38 | |||
| 39 | endmodule | ||
diff --git a/sim/tmp.sv b/sim/tmp.sv new file mode 100644 index 0000000..61e35f7 --- /dev/null +++ b/sim/tmp.sv | |||
| @@ -0,0 +1,41 @@ | |||
| 1 | module tmp | ||
| 2 | #( parameter UROM = "<no file specified>" | ||
| 3 | , parameter UIP_BITS = 15 | ||
| 4 | , parameter UROM_BITS = 8 | ||
| 5 | , parameter BUS_BITS = 16 | ||
| 6 | ) | ||
| 7 | ( input bit clk | ||
| 8 | , input bit reset | ||
| 9 | , input bit [UIP_BITS-1:0] uip | ||
| 10 | , inout bit [BUS_BITS-1:0] abus | ||
| 11 | , inout bit [BUS_BITS-1:0] dbus | ||
| 12 | ); | ||
| 13 | |||
| 14 | bit [BUS_BITS-1:0] x; | ||
| 15 | |||
| 16 | typedef enum | ||
| 17 | { LOAD | ||
| 18 | , LOAD_SEL0 | ||
| 19 | , OUTADDR | ||
| 20 | , OUTDATA | ||
| 21 | } CtrlBit; | ||
| 22 | |||
| 23 | bit [UROM_BITS-1:0] ctrl; | ||
| 24 | urom#(UROM, UIP_BITS, UROM_BITS) urom(uip, ctrl); | ||
| 25 | |||
| 26 | bit [0:0] sel; | ||
| 27 | assign sel = {ctrl[LOAD_SEL0]}; | ||
| 28 | |||
| 29 | assign abus = ctrl[OUTADDR] ? x : {(BUS_BITS){1'bZ}}; | ||
| 30 | assign dbus = ctrl[OUTDATA] ? x : {(BUS_BITS){1'bZ}}; | ||
| 31 | |||
| 32 | always @(posedge clk) begin | ||
| 33 | if (ctrl[LOAD]) begin | ||
| 34 | x <= | ||
| 35 | (sel == 0) ? dbus : | ||
| 36 | (sel == 1) ? abus : | ||
| 37 | {(BUS_BITS){1'bX}}; | ||
| 38 | end | ||
| 39 | end | ||
| 40 | |||
| 41 | endmodule | ||
diff --git a/sim/top.sv b/sim/top.sv new file mode 100644 index 0000000..6773739 --- /dev/null +++ b/sim/top.sv | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | module top | ||
| 2 | #( parameter UIP_BITS = 15 | ||
| 3 | , parameter UROM_BITS = 8 | ||
| 4 | , parameter BUS_BITS = 16 | ||
| 5 | , parameter MEM_BITS = 8 | ||
| 6 | ) | ||
| 7 | ( input bit clk // verilator public | ||
| 8 | , input bit reset // verilator public | ||
| 9 | ); | ||
| 10 | |||
| 11 | bit [UIP_BITS-1:0] uip; | ||
| 12 | bit [BUS_BITS-1:0] abus; | ||
| 13 | bit [BUS_BITS-1:0] dbus; | ||
| 14 | |||
| 15 | alu #("../out/alu.bin", UIP_BITS, UROM_BITS, BUS_BITS) alu(clk, reset, uip, abus, dbus); | ||
| 16 | control #("../out/control.bin", UIP_BITS, UROM_BITS, BUS_BITS, "../out/consts.0.bin", "../out/consts.1.bin", 'h7ff8) control(clk, reset, uip, abus, dbus); | ||
| 17 | decode #("../out/decode.bin", UIP_BITS, UROM_BITS, BUS_BITS, 12) decode(clk, reset, uip, abus, dbus); | ||
| 18 | memory #("../out/memory.bin", UIP_BITS, UROM_BITS, BUS_BITS, "../out/image.hex", MEM_BITS) memory(clk, reset, uip, abus, dbus); | ||
| 19 | pc #("../out/pc.bin", UIP_BITS, UROM_BITS, BUS_BITS, 0) pc(clk, reset, uip, abus, dbus); | ||
| 20 | rf #("../out/rf.bin", UIP_BITS, UROM_BITS, BUS_BITS, 3) rf(clk, reset, uip, abus, dbus); | ||
| 21 | tmp #("../out/tmp0.bin", UIP_BITS, UROM_BITS, BUS_BITS) tmp0(clk, reset, uip, abus, dbus); | ||
| 22 | tmp #("../out/tmp1.bin", UIP_BITS, UROM_BITS, BUS_BITS) tmp1(clk, reset, uip, abus, dbus); | ||
| 23 | uart #("../out/uart.bin", UIP_BITS, UROM_BITS, BUS_BITS) uart(clk, reset, uip, abus, dbus); | ||
| 24 | |||
| 25 | //always @(negedge clk) $display("pc=%x uip=%x abus=%x dbus=%x tmp0=%x tmp1=%x alu=%x regs=%x:%x:%x:...:%x", pc.addr, uip, abus, dbus, tmp0.x, tmp1.x, alu.x, rf.storage[0], rf.storage[1], rf.storage[2], rf.storage[7]); | ||
| 26 | |||
| 27 | endmodule | ||
diff --git a/sim/uart.sv b/sim/uart.sv new file mode 100644 index 0000000..3b434da --- /dev/null +++ b/sim/uart.sv | |||
| @@ -0,0 +1,47 @@ | |||
| 1 | module uart | ||
| 2 | #( parameter UROM = "<no file specified>" | ||
| 3 | , parameter UIP_BITS = 15 | ||
| 4 | , parameter UROM_BITS = 8 | ||
| 5 | , parameter BUS_BITS = 16 | ||
| 6 | ) | ||
| 7 | ( input bit clk | ||
| 8 | , input bit reset | ||
| 9 | , input bit [UIP_BITS-1:0] uip | ||
| 10 | , inout bit [BUS_BITS-1:0] abus | ||
| 11 | , inout bit [BUS_BITS-1:0] dbus | ||
| 12 | ); | ||
| 13 | |||
| 14 | bit txfull; | ||
| 15 | bit rxempty; | ||
| 16 | |||
| 17 | assign txfull = 0; | ||
| 18 | assign rxempty = 0; | ||
| 19 | |||
| 20 | typedef enum | ||
| 21 | { TX | ||
| 22 | , RX | ||
| 23 | , OUTDATA | ||
| 24 | , OUTDATA_SEL0 | ||
| 25 | } CtrlBit; | ||
| 26 | |||
| 27 | bit [UROM_BITS-1:0] ctrl; | ||
| 28 | urom#(UROM, UIP_BITS, UROM_BITS) urom(uip, ctrl); | ||
| 29 | |||
| 30 | bit [0:0] sel; | ||
| 31 | assign sel = {ctrl[OUTDATA_SEL0]}; | ||
| 32 | |||
| 33 | bit [BUS_BITS-1:0] dout; | ||
| 34 | assign dout = | ||
| 35 | (ctrl[RX]) ? {(BUS_BITS){1'b1}} : | ||
| 36 | (sel == 0) ? {{(BUS_BITS-1){1'b0}}, txfull} : | ||
| 37 | (sel == 1) ? {{(BUS_BITS-1){1'b0}}, rxempty} : | ||
| 38 | {(BUS_BITS){1'bX}}; | ||
| 39 | |||
| 40 | assign dbus = ctrl[OUTDATA] ? dout : {(BUS_BITS){1'bZ}}; | ||
| 41 | |||
| 42 | always @(posedge clk) begin | ||
| 43 | if (ctrl[TX]) | ||
| 44 | $display("tx %x", dbus[7:0]); | ||
| 45 | end | ||
| 46 | |||
| 47 | endmodule | ||
diff --git a/sim/urom.sv b/sim/urom.sv new file mode 100644 index 0000000..e88f6d7 --- /dev/null +++ b/sim/urom.sv | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | module urom | ||
| 2 | #( parameter UROM = "<no file specified>" | ||
| 3 | , parameter ADDR_BITS = 15 | ||
| 4 | , parameter DATA_BITS = 8 | ||
| 5 | ) | ||
| 6 | ( input bit [ADDR_BITS-1:0] addr | ||
| 7 | , output bit [DATA_BITS-1:0] data | ||
| 8 | ); | ||
| 9 | |||
| 10 | bit [DATA_BITS-1:0] storage [0:(1<<ADDR_BITS)-1]; | ||
| 11 | initial begin | ||
| 12 | automatic int fh; | ||
| 13 | fh = $fopen(UROM, "rb"); | ||
| 14 | $fread(storage, fh); | ||
| 15 | end | ||
| 16 | |||
| 17 | assign data = storage[addr]; | ||
| 18 | |||
| 19 | endmodule | ||
