summaryrefslogtreecommitdiff
path: root/sim
diff options
context:
space:
mode:
Diffstat (limited to 'sim')
-rw-r--r--sim/.gitignore2
-rw-r--r--sim/Makefile12
-rw-r--r--sim/alu.sv76
-rw-r--r--sim/control.sv54
-rw-r--r--sim/decode.sv82
-rw-r--r--sim/main.cpp61
-rw-r--r--sim/memory.sv35
-rw-r--r--sim/pc.sv36
-rw-r--r--sim/rf.sv39
-rw-r--r--sim/tmp.sv41
-rw-r--r--sim/top.sv27
-rw-r--r--sim/uart.sv47
-rw-r--r--sim/urom.sv19
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 @@
1run: build/Vtop
2 $<
3.PHONY: run
4
5build/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 @@
1module 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
14bit [BUS_BITS-1:0] x;
15
16typedef enum
17 { OP
18 , OP_SEL0
19 , OP_SEL1
20 , OP_SEL2
21 , OUTADDR
22 , OUTDATA
23 } CtrlBit;
24
25bit [UROM_BITS-1:0] ctrl;
26urom#(UROM, UIP_BITS, UROM_BITS) urom(uip, ctrl);
27
28bit [2:0] sel;
29assign sel = {ctrl[OP_SEL2], ctrl[OP_SEL1], ctrl[OP_SEL0]};
30
31bit [BUS_BITS-1:0] and_result;
32bit [BUS_BITS-1:0] or_result;
33bit [BUS_BITS-1:0] xor_result;
34bit [BUS_BITS-1:0] add_result;
35bit [BUS_BITS-1:0] sub_result;
36bit [BUS_BITS-1:0] cmp_result;
37bit [BUS_BITS-1:0] lshift_result;
38bit [BUS_BITS-1:0] rshift_result;
39
40assign and_result = abus & dbus;
41assign or_result = abus | dbus;
42assign xor_result = abus ^ dbus;
43assign add_result = abus + dbus;
44assign sub_result = abus - dbus;
45assign 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};
52assign lshift_result = (dbus >= BUS_BITS) ? 0 : (abus << dbus);
53assign rshift_result = (dbus >= BUS_BITS) ? 0 : (abus >> dbus);
54
55bit [BUS_BITS-1:0] newx;
56assign 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
67assign abus = ctrl[OUTADDR] ? x : {(BUS_BITS){1'bZ}};
68assign dbus = ctrl[OUTDATA] ? x : {(BUS_BITS){1'bZ}};
69
70always @(posedge clk) begin
71 if (ctrl[OP]) begin
72 x <= newx;
73 end
74end
75
76endmodule
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 @@
1module 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
17typedef enum
18 { HALT
19 , SET_UIP_COND
20 , NOCOND
21 , OUTADDR
22 , OUTDATA
23 } CtrlBit;
24
25bit [UROM_BITS-1:0] ctrl;
26urom#(UROM, UIP_BITS, UROM_BITS) urom(uip, ctrl);
27
28bit [UROM_BITS*2-1:0] constant;
29urom#(CONST_0, UIP_BITS, UROM_BITS) const_0(uip, constant[1*UROM_BITS-1:0*UROM_BITS]);
30urom#(CONST_1, UIP_BITS, UROM_BITS) const_1(uip, constant[2*UROM_BITS-1:1*UROM_BITS]);
31
32assign abus = ctrl[OUTADDR] ? constant : {(BUS_BITS){1'bZ}};
33assign dbus = ctrl[OUTDATA] ? constant : {(BUS_BITS){1'bZ}};
34
35bit cond;
36assign cond = (dbus != 0) || ctrl[NOCOND];
37
38always @(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
52end
53
54endmodule
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 @@
1module 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
15bit [OPCODE_BITS-1:0] opcode;
16bit [BUS_BITS-1:0] a;
17bit [BUS_BITS-1:0] b;
18bit needmore;
19
20bit [UIP_BITS-1:0] new_uip;
21assign new_uip = {opcode, {(UIP_BITS-OPCODE_BITS){1'b0}}};
22
23typedef enum
24 { CLEAR
25 , DECODE
26 , OUTADDR
27 , OUTADDR_SEL0
28 , OUTADDR_SEL1
29 , OUTDATA
30 , OUTDATA_SEL0
31 , OUTDATA_SEL1
32 } CtrlBit;
33
34bit [UROM_BITS-1:0] ctrl;
35urom#(UROM, UIP_BITS, UROM_BITS) urom(uip, ctrl);
36
37bit [1:0] asel;
38assign asel = {ctrl[OUTADDR_SEL1], ctrl[OUTADDR_SEL0]};
39
40bit [1:0] dsel;
41assign dsel = {ctrl[OUTDATA_SEL1], ctrl[OUTDATA_SEL0]};
42
43bit [BUS_BITS-1:0] aout;
44assign 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
50assign abus = ctrl[OUTADDR] ? aout : {(BUS_BITS){1'bZ}};
51
52bit [BUS_BITS-1:0] dout;
53assign dout =
54 (dsel == 0) ? a :
55 (dsel == 1) ? b :
56 (dsel == 2) ? {{(BUS_BITS-1){1'b0}}, needmore} :
57 {(BUS_BITS){1'bX}};
58
59assign dbus = ctrl[OUTDATA] ? dout : {(BUS_BITS){1'bZ}};
60
61always @(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
81end
82endmodule
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
8std::uint64_t phases = 0;
9
10double sc_time_stamp()
11{
12 return (double)phases / 2;
13}
14
15int 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 @@
1module 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
16bit [BYTE_BITS-1:0] storage [0:(1<<BUS_BITS)-1];
17initial $readmemh(IMAGE, storage);
18
19typedef enum
20 { STORE
21 , OUTDATA
22 } CtrlBit;
23
24bit [UROM_BITS-1:0] ctrl;
25urom#(UROM, UIP_BITS, UROM_BITS) urom(uip, ctrl);
26
27assign dbus = ctrl[OUTDATA] ? {{(BUS_BITS-BYTE_BITS){1'b0}}, storage[abus]} : {(BUS_BITS){1'bZ}};
28
29always @(posedge clk) begin
30 if (ctrl[STORE]) begin
31 storage[abus] <= dbus[BYTE_BITS-1:0];
32 end
33end
34
35endmodule
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 @@
1module 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
15bit [BUS_BITS-1:0] addr;
16
17typedef enum
18 { LOAD
19 , INCREMENT
20 , OUTADDR
21 } CtrlBit;
22
23bit [UROM_BITS-1:0] ctrl;
24urom#(UROM, UIP_BITS, UROM_BITS) urom(uip, ctrl);
25
26assign abus = ctrl[OUTADDR] ? addr : {(BUS_BITS){1'bZ}};
27
28always @(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
34end
35
36endmodule
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 @@
1module 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
15bit [BUS_BITS-1:0] storage [0:(1<<NAME_BITS)-1];
16
17typedef enum
18 { STORE
19 , RESET
20 , OUTDATA
21 } CtrlBit;
22
23bit [UROM_BITS-1:0] ctrl;
24urom#(UROM, UIP_BITS, UROM_BITS) urom(uip, ctrl);
25
26assign dbus = ctrl[OUTDATA] ? storage[abus[NAME_BITS-1:0]] : {(BUS_BITS){1'bZ}};
27
28always @(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
37end
38
39endmodule
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 @@
1module 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
14bit [BUS_BITS-1:0] x;
15
16typedef enum
17 { LOAD
18 , LOAD_SEL0
19 , OUTADDR
20 , OUTDATA
21 } CtrlBit;
22
23bit [UROM_BITS-1:0] ctrl;
24urom#(UROM, UIP_BITS, UROM_BITS) urom(uip, ctrl);
25
26bit [0:0] sel;
27assign sel = {ctrl[LOAD_SEL0]};
28
29assign abus = ctrl[OUTADDR] ? x : {(BUS_BITS){1'bZ}};
30assign dbus = ctrl[OUTDATA] ? x : {(BUS_BITS){1'bZ}};
31
32always @(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
39end
40
41endmodule
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 @@
1module 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
11bit [UIP_BITS-1:0] uip;
12bit [BUS_BITS-1:0] abus;
13bit [BUS_BITS-1:0] dbus;
14
15alu #("../out/alu.bin", UIP_BITS, UROM_BITS, BUS_BITS) alu(clk, reset, uip, abus, dbus);
16control #("../out/control.bin", UIP_BITS, UROM_BITS, BUS_BITS, "../out/consts.0.bin", "../out/consts.1.bin", 'h7ff8) control(clk, reset, uip, abus, dbus);
17decode #("../out/decode.bin", UIP_BITS, UROM_BITS, BUS_BITS, 12) decode(clk, reset, uip, abus, dbus);
18memory #("../out/memory.bin", UIP_BITS, UROM_BITS, BUS_BITS, "../out/image.hex", MEM_BITS) memory(clk, reset, uip, abus, dbus);
19pc #("../out/pc.bin", UIP_BITS, UROM_BITS, BUS_BITS, 0) pc(clk, reset, uip, abus, dbus);
20rf #("../out/rf.bin", UIP_BITS, UROM_BITS, BUS_BITS, 3) rf(clk, reset, uip, abus, dbus);
21tmp #("../out/tmp0.bin", UIP_BITS, UROM_BITS, BUS_BITS) tmp0(clk, reset, uip, abus, dbus);
22tmp #("../out/tmp1.bin", UIP_BITS, UROM_BITS, BUS_BITS) tmp1(clk, reset, uip, abus, dbus);
23uart #("../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
27endmodule
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 @@
1module 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
14bit txfull;
15bit rxempty;
16
17assign txfull = 0;
18assign rxempty = 0;
19
20typedef enum
21 { TX
22 , RX
23 , OUTDATA
24 , OUTDATA_SEL0
25 } CtrlBit;
26
27bit [UROM_BITS-1:0] ctrl;
28urom#(UROM, UIP_BITS, UROM_BITS) urom(uip, ctrl);
29
30bit [0:0] sel;
31assign sel = {ctrl[OUTDATA_SEL0]};
32
33bit [BUS_BITS-1:0] dout;
34assign 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
40assign dbus = ctrl[OUTDATA] ? dout : {(BUS_BITS){1'bZ}};
41
42always @(posedge clk) begin
43 if (ctrl[TX])
44 $display("tx %x", dbus[7:0]);
45end
46
47endmodule
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 @@
1module 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
10bit [DATA_BITS-1:0] storage [0:(1<<ADDR_BITS)-1];
11initial begin
12 automatic int fh;
13 fh = $fopen(UROM, "rb");
14 $fread(storage, fh);
15end
16
17assign data = storage[addr];
18
19endmodule