Explorar o código

Working processor

Implemented following instructions:
Arithemtic/Logical: MOVE, ADD, SUB, AND, OR, XOR, MUL, DIV, INC, DEC
Data: LWHI, SWHI, LWLO, SWLO, PUSH, POP
Min %!s(int64=6) %!d(string=hai) anos
pai
achega
12417f0cb5

+ 2 - 2
UCL_project_y3.qsf

@@ -136,7 +136,6 @@ set_global_assignment -name SYSTEMVERILOG_FILE src/blocks/reg_file.sv
 set_global_assignment -name SYSTEMVERILOG_FILE src/blocks/memory.sv
 set_global_assignment -name QIP_FILE quartus/pll_clk.qip
 set_global_assignment -name SYSTEMVERILOG_FILE src/blocks/alu.sv
-set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
 set_global_assignment -name EDA_TEST_BENCH_FILE src/blocks/alu.sv -section_id testbench_1
 set_global_assignment -name EDA_TEST_BENCH_FILE src/blocks/instr_mem.sv -section_id testbench_1
 set_global_assignment -name EDA_TEST_BENCH_FILE src/blocks/memory.sv -section_id testbench_1
@@ -144,4 +143,5 @@ set_global_assignment -name EDA_TEST_BENCH_FILE src/blocks/sdram_control.sv -sec
 set_global_assignment -name EDA_TEST_BENCH_FILE src/risc/general.sv -section_id testbench_1
 set_global_assignment -name EDA_TEST_BENCH_FILE src/risc/controller.sv -section_id testbench_1
 set_global_assignment -name EDA_TEST_BENCH_FILE src/risc/datapath.sv -section_id testbench_1
-set_global_assignment -name EDA_TEST_BENCH_FILE src/risc/cpu.sv -section_id testbench_1
+set_global_assignment -name EDA_TEST_BENCH_FILE src/risc/cpu.sv -section_id testbench_1
+set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

+ 10 - 0
memory/risc8_test.mem

@@ -0,0 +1,10 @@
+00 0f 08 05 0a 11 02 21
+02 31 02 41 02 51 02 00
+64 61 be 02 71 be 76 be
+b0 b0 b1 b1 00 32 05 4f
+a1 a7 01 00 00 00 00 04
+a0 01 00 00 a2 01 00 00
+c2 ff 00 11 05 22 0a 33
+0f 44 c0 c4 c8 cc 0f 55
+cc 00 00 c1 c1 c1 c1 c1
+

+ 28 - 31
simulation/modelsim/risc8_tb_wave.do

@@ -1,31 +1,28 @@
-clk = St1
-rst = St0
-interrupt = HiZ
-com_rd = zzzzzzzz
-imm = xxxxxx
-com_wr = xxxxxxxx
-com_addr = xxxxxxxx
-mem_rd = xxxxxxxxxxxxxxxx
-mem_wr = zzzzzzzzzzzzzzzz
-pc = 4
-r1 = 15
-r2 = 10
-reg_wr = 0
-srcA = 15
-srcB = 10
-alu_rlo = 0
-alu_rhi = x
-cout = x
-cin = x
-alu_eq = x
-alu_gt = x
-alu_zero = 1
-alu_srcA = HiZ
-alu_srcB = HiZ
-alu_op = HiZ
-bconst = 0
-pc_off = 00000001
-pcn = 0000000000000101
-pca = 0000000000000100
-interrupt_flag = 00000000
-#implicit-wire#0 = Not Loggable
+onerror {resume}
+quietly WaveActivateNextPane {} 0
+add wave -noupdate -label Clock /risc8_cpu_tb/clk
+add wave -noupdate -label Reset /risc8_cpu_tb/rst
+add wave -noupdate -label ProgramCount -radix unsigned /risc8_cpu_tb/cpu0/pc
+add wave -noupdate -label RegisterFile -radix hexadecimal /risc8_cpu_tb/cpu0/dpath0/reg0/registry
+add wave -noupdate -label Instruction /risc8_cpu_tb/cpu0/ctrl0/op
+add wave -noupdate /risc8_cpu_tb/cpu0/ctrl0/instr
+add wave -noupdate -label r1 -radix hexadecimal /risc8_cpu_tb/cpu0/dpath0/r1
+add wave -noupdate -label RamAddr /risc8_cpu_tb/ram_addr
+TreeUpdate [SetDefaultTree]
+WaveRestoreCursors {{Cursor 1} {512 ns} 0}
+quietly wave cursor active 1
+configure wave -namecolwidth 157
+configure wave -valuecolwidth 100
+configure wave -justifyvalue left
+configure wave -signalnamewidth 0
+configure wave -snapdistance 10
+configure wave -datasetprefix 0
+configure wave -rowmargin 4
+configure wave -childrowmargin 2
+configure wave -gridoffset 0
+configure wave -gridperiod 1
+configure wave -griddelta 40
+configure wave -timeline 0
+configure wave -timelineunits ns
+update
+WaveRestoreZoom {461 ns} {524 ns}

+ 44 - 50
src/risc/controller.csv

@@ -1,50 +1,44 @@
-instr,cdi.alu_op,cdi.selb,cdi.rw_en,cdi.selr,mem_rd,mem_wr,cdi.isize
-CPY0,ALU_NONE,SB_IMM,1,SR_IMM,0,0,1
-CPY1,ALU_NONE,SB_IMM,1,SR_IMM,0,0,1
-CPY2,ALU_NONE,SB_IMM,1,SR_IMM,0,0,1
-CPY3,ALU_NONE,SB_IMM,1,SR_IMM,0,0,1
-MOVE,ALU_NONE,SB_NONE,1,SR_COM,0,0,0
-,,,,,,,
-ADD,ALU_ADD,SB_REG,1,SR_ALUL,0,0,0
-SUB,ALU_SUB,SB_REG,1,SR_ALUL,0,0,0
-AND,ALU_AND,SB_REG,1,SR_ALUL,0,0,0
-OR,ALU_OR,SB_REG,1,SR_ALUL,0,0,0
-XOR,ALU_XOR,SB_REG,1,SR_ALUL,0,0,0
-MUL,ALU_MUL,SB_REG,1,SR_ALUL,0,0,0
-DIV,ALU_DIV,SB_REG,1,SR_ALUL,0,0,0
-BR,ALU_NONE,SB_NONE,0,SR_NONE,0,0,2
-,,,,,,,
-SLL,ALU_SL,SB_REG,1,SR_ALUL,0,0,0
-SRL,ALU_SR,SB_REG,1,SR_ALUL,0,0,0
-SRA,ALU_RA,SB_REG,1,SR_ALUL,0,0,0
-SRAS,ALU_RAS,SB_REG,1,SR_ALUL,0,0,0
-,,,,,,,
-LWHI,ALU_NONE,SB_NONE,1,SR_MEMH,0,1,3
-SWHI,ALU_NONE,SB_NONE,0,SR_NONE,1,0,3
-LWLO,ALU_NONE,SB_NONE,1,SR_MEML,0,1,3
-SWLO,ALU_NONE,SB_NONE,0,SR_NONE,1,0,3
-,,,,,,,
-INC,ALU_ADD,SB_1,1,SR_ALUL,0,0,0
-DEC,ALU_SUB,SB_1,1,SR_ALUL,0,0,0
-GETAH,ALU_NONE,SB_NONE,1,SR_ALUH,0,0,0
-GETIF,ALU_NONE,SB_NONE,1,SR_INTR,0,0,0
-,,,,,,,
-PUSH,ALU_NONE,SB_NONE,0,SR_NONE,0,0,0
-POP,ALU_NONE,SB_NONE,1,SR_NONE,0,0,0
-COM,ALU_NONE,SB_NONE,1,SR_NONE,0,0,1
-,,,,,,,
-CALL,ALU_NONE,SB_NONE,0,SR_NONE,0,0,2
-RET,ALU_NONE,SB_NONE,0,SR_NONE,0,0,0
-JUMP,ALU_NONE,SB_NONE,0,SR_NONE,0,0,2
-RETI,ALU_NONE,SB_NONE,0,SR_NONE,0,0,0
-CLC,ALU_NONE,SB_NONE,0,SR_NONE,0,0,0
-SETC,ALU_NONE,SB_NONE,0,SR_NONE,0,0,0
-CLS,ALU_NONE,SB_NONE,0,SR_NONE,0,0,0
-SETS,ALU_NONE,SB_NONE,0,SR_NONE,0,0,0
-SSETS,ALU_NONE,SB_NONE,0,SR_NONE,0,0,0
-CLN,ALU_NONE,SB_NONE,0,SR_NONE,0,0,0
-SETN,ALU_NONE,SB_NONE,0,SR_NONE,0,0,0
-SSETN,ALU_NONE,SB_NONE,0,SR_NONE,0,0,0
-RJUMP,ALU_NONE,SB_NONE,0,SR_NONE,0,0,2
-RBWI,ALU_NONE,SB_NONE,0,SR_NONE,0,0,1
-default,ALU_NONE,SB_NONE,0,SR_NONE,0,0,0
+   instr, cdi.alu_op, cdi.selb, cdi.rw_en, cdi.selr, mem_rd, mem_wr, cdi.isize,cdi.selo ,cdi.stackop
+    CPY0,   ALU_NONE,   SB_IMM,         1,   SR_IMM,      0,      0,         1,SO_MEML , ST_SKIP
+    CPY1,   ALU_NONE,   SB_IMM,         1,   SR_IMM,      0,      0,         1,SO_MEML , ST_SKIP
+    CPY2,   ALU_NONE,   SB_IMM,         1,   SR_IMM,      0,      0,         1,SO_MEML , ST_SKIP
+    CPY3,   ALU_NONE,   SB_IMM,         1,   SR_IMM,      0,      0,         1,SO_MEML , ST_SKIP
+    MOVE,   ALU_NONE,  SB_NONE,         1,   SR_REG,      0,      0,         0,SO_MEML , ST_SKIP
+     ADD,    ALU_ADD,   SB_REG,         1,  SR_ALUL,      0,      0,         0,SO_MEML , ST_SKIP
+     SUB,    ALU_SUB,   SB_REG,         1,  SR_ALUL,      0,      0,         0,SO_MEML , ST_SKIP
+     AND,    ALU_AND,   SB_REG,         1,  SR_ALUL,      0,      0,         0,SO_MEML , ST_SKIP
+      OR,     ALU_OR,   SB_REG,         1,  SR_ALUL,      0,      0,         0,SO_MEML , ST_SKIP
+     XOR,    ALU_XOR,   SB_REG,         1,  SR_ALUL,      0,      0,         0,SO_MEML , ST_SKIP
+     MUL,    ALU_MUL,   SB_REG,         1,  SR_ALUL,      0,      0,         0,SO_MEML , ST_SKIP
+     DIV,    ALU_DIV,   SB_REG,         1,  SR_ALUL,      0,      0,         0,SO_MEML , ST_SKIP
+      BR,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      0,         2,SO_MEML , ST_SKIP
+     SLL,     ALU_SL,   SB_REG,         1,  SR_ALUL,      0,      0,         0,SO_MEML , ST_SKIP
+     SRL,     ALU_SR,   SB_REG,         1,  SR_ALUL,      0,      0,         0,SO_MEML , ST_SKIP
+     SRA,     ALU_RA,   SB_REG,         1,  SR_ALUL,      0,      0,         0,SO_MEML , ST_SKIP
+    SRAS,    ALU_RAS,   SB_REG,         1,  SR_ALUL,      0,      0,         0,SO_MEML , ST_SKIP
+    LWHI,   ALU_NONE,  SB_NONE,         1,  SR_MEMH,      1,      0,         3,SO_MEML , ST_SKIP
+    SWHI,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      0,         0,SO_MEMH , ST_SKIP
+    LWLO,   ALU_NONE,  SB_NONE,         1,  SR_MEML,      1,      0,         3,SO_MEML , ST_SKIP
+    SWLO,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      1,         3,SO_MEML , ST_SKIP
+     INC,    ALU_ADD,     SB_1,         1,  SR_ALUL,      0,      0,         0,SO_MEML , ST_SKIP
+     DEC,    ALU_SUB,     SB_1,         1,  SR_ALUL,      0,      0,         0,SO_MEML , ST_SKIP
+   GETAH,   ALU_NONE,  SB_NONE,         1,  SR_ALUH,      0,      0,         0,SO_MEML , ST_SKIP
+   GETIF,   ALU_NONE,  SB_NONE,         1,  SR_INTR,      0,      0,         0,SO_MEML , ST_SKIP
+    PUSH,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      1,         0,SO_MEML ,  ST_SUB
+     POP,   ALU_NONE,  SB_NONE,         1,  SR_MEML,      1,      0,         0,SO_MEML ,  ST_ADD
+     COM,   ALU_NONE,  SB_NONE,         1,   SR_COM,      0,      0,         1, SO_COM , ST_SKIP
+    CALL,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      0,         2,SO_MEML , ST_SKIP
+     RET,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      0,         0,SO_MEML , ST_SKIP
+    JUMP,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      0,         2,SO_MEML , ST_SKIP
+    RETI,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      0,         0,SO_MEML , ST_SKIP
+     CLC,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      0,         0,SO_MEML , ST_SKIP
+    SETC,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      0,         0,SO_MEML , ST_SKIP
+     CLS,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      0,         0,SO_MEML , ST_SKIP
+    SETS,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      0,         0,SO_MEML , ST_SKIP
+   SSETS,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      0,         0,SO_MEML , ST_SKIP
+     CLN,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      0,         0,SO_MEML , ST_SKIP
+    SETN,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      0,         0,SO_MEML , ST_SKIP
+   SSETN,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      0,         0,SO_MEML , ST_SKIP
+   RJUMP,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      0,         2,SO_MEML , ST_SKIP
+    RBWI,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      0,         1,SO_MEML , ST_SKIP
+ default,   ALU_NONE,  SB_NONE,         0,  SR_NONE,      0,      0,         0,SO_MEML , ST_SKIP

+ 387 - 301
src/risc/controller.sv

@@ -21,517 +21,603 @@ module controller8(
     always_comb begin
     casez(instr)
         CPY0   : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_IMM;
-            cdi.rw_en  = 1;
-            cdi.selr   = SR_IMM;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 1;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_IMM;
+            cdi.rw_en   = 1;
+            cdi.selr    = SR_IMM;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 1;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = CPY0;
             `endif
         end
         CPY1   : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_IMM;
-            cdi.rw_en  = 1;
-            cdi.selr   = SR_IMM;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 1;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_IMM;
+            cdi.rw_en   = 1;
+            cdi.selr    = SR_IMM;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 1;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = CPY1;
             `endif
         end
         CPY2   : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_IMM;
-            cdi.rw_en  = 1;
-            cdi.selr   = SR_IMM;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 1;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_IMM;
+            cdi.rw_en   = 1;
+            cdi.selr    = SR_IMM;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 1;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = CPY2;
             `endif
         end
         CPY3   : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_IMM;
-            cdi.rw_en  = 1;
-            cdi.selr   = SR_IMM;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 1;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_IMM;
+            cdi.rw_en   = 1;
+            cdi.selr    = SR_IMM;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 1;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = CPY3;
             `endif
         end
         MOVE   : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_NONE;
-            cdi.rw_en  = 1;
-            cdi.selr   = SR_COM;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_NONE;
+            cdi.rw_en   = 1;
+            cdi.selr    = SR_REG;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = MOVE;
             `endif
         end
         ADD    : begin
-            cdi.alu_op = ALU_ADD;
-            cdi.selb   = SB_REG;
-            cdi.rw_en  = 1;
-            cdi.selr   = SR_ALUL;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_ADD;
+            cdi.selb    = SB_REG;
+            cdi.rw_en   = 1;
+            cdi.selr    = SR_ALUL;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = ADD;
             `endif
         end
         SUB    : begin
-            cdi.alu_op = ALU_SUB;
-            cdi.selb   = SB_REG;
-            cdi.rw_en  = 1;
-            cdi.selr   = SR_ALUL;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_SUB;
+            cdi.selb    = SB_REG;
+            cdi.rw_en   = 1;
+            cdi.selr    = SR_ALUL;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = SUB;
             `endif
         end
         AND    : begin
-            cdi.alu_op = ALU_AND;
-            cdi.selb   = SB_REG;
-            cdi.rw_en  = 1;
-            cdi.selr   = SR_ALUL;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_AND;
+            cdi.selb    = SB_REG;
+            cdi.rw_en   = 1;
+            cdi.selr    = SR_ALUL;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = AND;
             `endif
         end
         OR     : begin
-            cdi.alu_op = ALU_OR;
-            cdi.selb   = SB_REG;
-            cdi.rw_en  = 1;
-            cdi.selr   = SR_ALUL;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_OR;
+            cdi.selb    = SB_REG;
+            cdi.rw_en   = 1;
+            cdi.selr    = SR_ALUL;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = OR;
             `endif
         end
         XOR    : begin
-            cdi.alu_op = ALU_XOR;
-            cdi.selb   = SB_REG;
-            cdi.rw_en  = 1;
-            cdi.selr   = SR_ALUL;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_XOR;
+            cdi.selb    = SB_REG;
+            cdi.rw_en   = 1;
+            cdi.selr    = SR_ALUL;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = XOR;
             `endif
         end
         MUL    : begin
-            cdi.alu_op = ALU_MUL;
-            cdi.selb   = SB_REG;
-            cdi.rw_en  = 1;
-            cdi.selr   = SR_ALUL;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_MUL;
+            cdi.selb    = SB_REG;
+            cdi.rw_en   = 1;
+            cdi.selr    = SR_ALUL;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = MUL;
             `endif
         end
         DIV    : begin
-            cdi.alu_op = ALU_DIV;
-            cdi.selb   = SB_REG;
-            cdi.rw_en  = 1;
-            cdi.selr   = SR_ALUL;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_DIV;
+            cdi.selb    = SB_REG;
+            cdi.rw_en   = 1;
+            cdi.selr    = SR_ALUL;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = DIV;
             `endif
         end
         BR     : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_NONE;
-            cdi.rw_en  = 0;
-            cdi.selr   = SR_NONE;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 2;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_NONE;
+            cdi.rw_en   = 0;
+            cdi.selr    = SR_NONE;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 2;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = BR;
             `endif
         end
         SLL    : begin
-            cdi.alu_op = ALU_SL;
-            cdi.selb   = SB_REG;
-            cdi.rw_en  = 1;
-            cdi.selr   = SR_ALUL;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_SL;
+            cdi.selb    = SB_REG;
+            cdi.rw_en   = 1;
+            cdi.selr    = SR_ALUL;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = SLL;
             `endif
         end
         SRL    : begin
-            cdi.alu_op = ALU_SR;
-            cdi.selb   = SB_REG;
-            cdi.rw_en  = 1;
-            cdi.selr   = SR_ALUL;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_SR;
+            cdi.selb    = SB_REG;
+            cdi.rw_en   = 1;
+            cdi.selr    = SR_ALUL;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = SRL;
             `endif
         end
         SRA    : begin
-            cdi.alu_op = ALU_RA;
-            cdi.selb   = SB_REG;
-            cdi.rw_en  = 1;
-            cdi.selr   = SR_ALUL;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_RA;
+            cdi.selb    = SB_REG;
+            cdi.rw_en   = 1;
+            cdi.selr    = SR_ALUL;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = SRA;
             `endif
         end
         SRAS   : begin
-            cdi.alu_op = ALU_RAS;
-            cdi.selb   = SB_REG;
-            cdi.rw_en  = 1;
-            cdi.selr   = SR_ALUL;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_RAS;
+            cdi.selb    = SB_REG;
+            cdi.rw_en   = 1;
+            cdi.selr    = SR_ALUL;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = SRAS;
             `endif
         end
         LWHI   : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_NONE;
-            cdi.rw_en  = 1;
-            cdi.selr   = SR_MEMH;
-            mem_rd     = 0;
-            mem_wr     = 1;
-            cdi.isize  = 3;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_NONE;
+            cdi.rw_en   = 1;
+            cdi.selr    = SR_MEMH;
+            mem_rd      = 1;
+            mem_wr      = 0;
+            cdi.isize   = 3;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = LWHI;
             `endif
         end
         SWHI   : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_NONE;
-            cdi.rw_en  = 0;
-            cdi.selr   = SR_NONE;
-            mem_rd     = 1;
-            mem_wr     = 0;
-            cdi.isize  = 3;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_NONE;
+            cdi.rw_en   = 0;
+            cdi.selr    = SR_NONE;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEMH;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = SWHI;
             `endif
         end
         LWLO   : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_NONE;
-            cdi.rw_en  = 1;
-            cdi.selr   = SR_MEML;
-            mem_rd     = 0;
-            mem_wr     = 1;
-            cdi.isize  = 3;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_NONE;
+            cdi.rw_en   = 1;
+            cdi.selr    = SR_MEML;
+            mem_rd      = 1;
+            mem_wr      = 0;
+            cdi.isize   = 3;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = LWLO;
             `endif
         end
         SWLO   : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_NONE;
-            cdi.rw_en  = 0;
-            cdi.selr   = SR_NONE;
-            mem_rd     = 1;
-            mem_wr     = 0;
-            cdi.isize  = 3;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_NONE;
+            cdi.rw_en   = 0;
+            cdi.selr    = SR_NONE;
+            mem_rd      = 0;
+            mem_wr      = 1;
+            cdi.isize   = 3;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = SWLO;
             `endif
         end
         INC    : begin
-            cdi.alu_op = ALU_ADD;
-            cdi.selb   = SB_1;
-            cdi.rw_en  = 1;
-            cdi.selr   = SR_ALUL;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_ADD;
+            cdi.selb    = SB_1;
+            cdi.rw_en   = 1;
+            cdi.selr    = SR_ALUL;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = INC;
             `endif
         end
         DEC    : begin
-            cdi.alu_op = ALU_SUB;
-            cdi.selb   = SB_1;
-            cdi.rw_en  = 1;
-            cdi.selr   = SR_ALUL;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_SUB;
+            cdi.selb    = SB_1;
+            cdi.rw_en   = 1;
+            cdi.selr    = SR_ALUL;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = DEC;
             `endif
         end
         GETAH  : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_NONE;
-            cdi.rw_en  = 1;
-            cdi.selr   = SR_ALUH;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_NONE;
+            cdi.rw_en   = 1;
+            cdi.selr    = SR_ALUH;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = GETAH;
             `endif
         end
         GETIF  : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_NONE;
-            cdi.rw_en  = 1;
-            cdi.selr   = SR_INTR;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_NONE;
+            cdi.rw_en   = 1;
+            cdi.selr    = SR_INTR;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = GETIF;
             `endif
         end
         PUSH   : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_NONE;
-            cdi.rw_en  = 0;
-            cdi.selr   = SR_NONE;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_NONE;
+            cdi.rw_en   = 0;
+            cdi.selr    = SR_NONE;
+            mem_rd      = 0;
+            mem_wr      = 1;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SUB;
             `ifdef ADDOP
             op = PUSH;
             `endif
         end
         POP    : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_NONE;
-            cdi.rw_en  = 1;
-            cdi.selr   = SR_NONE;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_NONE;
+            cdi.rw_en   = 1;
+            cdi.selr    = SR_MEML;
+            mem_rd      = 1;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_ADD;
             `ifdef ADDOP
             op = POP;
             `endif
         end
         COM    : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_NONE;
-            cdi.rw_en  = 1;
-            cdi.selr   = SR_NONE;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 1;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_NONE;
+            cdi.rw_en   = 1;
+            cdi.selr    = SR_COM;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 1;
+            cdi.selo    = SO_COM;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = COM;
             `endif
         end
         CALL   : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_NONE;
-            cdi.rw_en  = 0;
-            cdi.selr   = SR_NONE;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 2;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_NONE;
+            cdi.rw_en   = 0;
+            cdi.selr    = SR_NONE;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 2;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = CALL;
             `endif
         end
         RET    : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_NONE;
-            cdi.rw_en  = 0;
-            cdi.selr   = SR_NONE;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_NONE;
+            cdi.rw_en   = 0;
+            cdi.selr    = SR_NONE;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = RET;
             `endif
         end
         JUMP   : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_NONE;
-            cdi.rw_en  = 0;
-            cdi.selr   = SR_NONE;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 2;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_NONE;
+            cdi.rw_en   = 0;
+            cdi.selr    = SR_NONE;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 2;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = JUMP;
             `endif
         end
         RETI   : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_NONE;
-            cdi.rw_en  = 0;
-            cdi.selr   = SR_NONE;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_NONE;
+            cdi.rw_en   = 0;
+            cdi.selr    = SR_NONE;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = RETI;
             `endif
         end
         CLC    : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_NONE;
-            cdi.rw_en  = 0;
-            cdi.selr   = SR_NONE;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_NONE;
+            cdi.rw_en   = 0;
+            cdi.selr    = SR_NONE;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = CLC;
             `endif
         end
         SETC   : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_NONE;
-            cdi.rw_en  = 0;
-            cdi.selr   = SR_NONE;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_NONE;
+            cdi.rw_en   = 0;
+            cdi.selr    = SR_NONE;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = SETC;
             `endif
         end
         CLS    : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_NONE;
-            cdi.rw_en  = 0;
-            cdi.selr   = SR_NONE;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_NONE;
+            cdi.rw_en   = 0;
+            cdi.selr    = SR_NONE;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = CLS;
             `endif
         end
         SETS   : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_NONE;
-            cdi.rw_en  = 0;
-            cdi.selr   = SR_NONE;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_NONE;
+            cdi.rw_en   = 0;
+            cdi.selr    = SR_NONE;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = SETS;
             `endif
         end
         SSETS  : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_NONE;
-            cdi.rw_en  = 0;
-            cdi.selr   = SR_NONE;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_NONE;
+            cdi.rw_en   = 0;
+            cdi.selr    = SR_NONE;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = SSETS;
             `endif
         end
         CLN    : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_NONE;
-            cdi.rw_en  = 0;
-            cdi.selr   = SR_NONE;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_NONE;
+            cdi.rw_en   = 0;
+            cdi.selr    = SR_NONE;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = CLN;
             `endif
         end
         SETN   : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_NONE;
-            cdi.rw_en  = 0;
-            cdi.selr   = SR_NONE;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_NONE;
+            cdi.rw_en   = 0;
+            cdi.selr    = SR_NONE;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = SETN;
             `endif
         end
         SSETN  : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_NONE;
-            cdi.rw_en  = 0;
-            cdi.selr   = SR_NONE;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_NONE;
+            cdi.rw_en   = 0;
+            cdi.selr    = SR_NONE;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = SSETN;
             `endif
         end
         RJUMP  : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_NONE;
-            cdi.rw_en  = 0;
-            cdi.selr   = SR_NONE;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 2;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_NONE;
+            cdi.rw_en   = 0;
+            cdi.selr    = SR_NONE;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 2;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = RJUMP;
             `endif
         end
         RBWI   : begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_NONE;
-            cdi.rw_en  = 0;
-            cdi.selr   = SR_NONE;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 1;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_NONE;
+            cdi.rw_en   = 0;
+            cdi.selr    = SR_NONE;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 1;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
             `ifdef ADDOP
             op = RBWI;
             `endif
         end
         default: begin
-            cdi.alu_op = ALU_NONE;
-            cdi.selb   = SB_NONE;
-            cdi.rw_en  = 0;
-            cdi.selr   = SR_NONE;
-            mem_rd     = 0;
-            mem_wr     = 0;
-            cdi.isize  = 0;
+            cdi.alu_op  = ALU_NONE;
+            cdi.selb    = SB_NONE;
+            cdi.rw_en   = 0;
+            cdi.selr    = SR_NONE;
+            mem_rd      = 0;
+            mem_wr      = 0;
+            cdi.isize   = 0;
+            cdi.selo    = SO_MEML;
+            cdi.stackop = ST_SKIP;
         end
     endcase
     end

+ 22 - 1
src/risc/cpu.sv

@@ -43,6 +43,10 @@ module risc8_cpu(processor_port port);
 			.imm(instr[31:8]),
 			.mem_rd(port.ram_rd_data),
 			.mem_wr(port.ram_wr_data),
+			.mem_addr(port.ram_addr),
+			.com_addr(port.com_addr),
+			.com_rd(port.com_rd),
+			.com_wr(port.com_wr),
 			.pc(pc)
 	);
 
@@ -58,6 +62,8 @@ module risc8_cpu_tb;
 	logic ram_wr_en;
 	logic ram_rd_en;
 
+	word com_addr, com_wr, com_rd;
+
 	processor_port port0(
 		.clk(clk),
 		.rst(rst),
@@ -65,8 +71,17 @@ module risc8_cpu_tb;
 		.ram_wr_data(ram_wr),
 		.ram_rd_data(ram_rd),
 		.ram_wr_en(ram_wr_en),
-		.ram_rd_en(ram_rd_en)
+		.ram_rd_en(ram_rd_en),
+		.com_addr(com_addr),
+		.com_wr(com_wr),
+		.com_rd(com_rd)
 	);
+
+	always_comb begin
+		if(com_addr != 'h00) begin
+			com_rd = com_addr^com_wr;
+		end else com_rd = 'h00;
+	end
 	
 	risc8_cpu #(.PROGRAM("../../memory/risc8_test.mem")) cpu0(port0);
 	
@@ -91,5 +106,11 @@ module risc8_cpu_tb;
 		rst = 1;
 		#10ns;
 		rst = 0;
+		if (cpu0.instr === 'x) $stop;
 	end
 endmodule
+
+module cpu_tb;
+	risc8_cpu_tb cpu_tb0();
+endmodule
+

+ 57 - 6
src/risc/datapath.sv

@@ -10,7 +10,8 @@ module datapath8(
 		output word com_wr, com_addr,
 		input  [15:0] mem_rd,
 		output [15:0] mem_wr,
-		output reg [15:0] pc
+		output reg [15:0] pc,
+		output reg [23:0] mem_addr
 );
 	
 	word r1, r2, reg_wr;
@@ -25,14 +26,21 @@ module datapath8(
 			.wr_en(cdi.rw_en)
 	);
 
-	word srcA, srcB, alu_rlo, alu_rhi;
+	word srcA, srcB, alu_rlo, alu_rhi, alu_rhit;
 	logic cout, cin, alu_eq, alu_gt, alu_zero, alu_sign;
 	assign cdi.alu_comp = {alu_eq, alu_gt, alu_zero};
 	assign alu_sign = 0;
 	always_ff@(posedge clk) begin
-			if(rst) cin <= 0;
-			else if(cdi.alu_op == ALU_ADD || cdi.alu_op == ALU_SUB)
+			if(rst) begin
+					cin <= '0;
+					alu_rhi <= '0;
+			end else begin
+
+			if((cdi.alu_op == ALU_ADD)||(cdi.alu_op == ALU_SUB))
 					cin <= cout;
+			if((cdi.alu_op == ALU_MUL)||(cdi.alu_op == ALU_DIV))
+					alu_rhi <= alu_rhit;
+			end
 	end
 
 	alu#(.WORD(8)) alu0(
@@ -40,7 +48,7 @@ module datapath8(
 		.b(srcB),
 		.op(cdi.alu_op),
 		.r(alu_rlo),
-		.r_high(alu_rhi),
+		.r_high(alu_rhit),
 		.zero(alu_zero),
 		.eq(alu_eq),
 		.gt(alu_gt),
@@ -75,6 +83,48 @@ module datapath8(
 		else if(interrupt) interrupt_flag <= com_rd;
 	end
 	
+	
+	// ======================== //
+	// 			Stack 			//
+	// ======================== //
+
+	logic [15:0] sp, sp_add, sp_next, sp_data;  // Stack pointer 
+	word st_lo, st_rd, st_wr;  // Stack data low byte reg
+	logic [23:0] sp_addr;
+	always_comb begin
+		sp_add = (cdi.stackop == ST_ADD) ? 'h0001 : 'hffff;
+		sp_next = sp + sp_add;
+		sp_addr = {9'b1111_1111_1, (cdi.stackop == ST_ADD) ? sp_next[15:1] : sp[15:1]};
+		st_rd = (sp[0]) ? mem_rd[7:0] : mem_rd[15:8];
+		st_wr = (sp[0]) ? r1 : st_lo;
+	end
+	
+	always_ff@(posedge clk) begin
+			if(rst)	sp <= 'hffff;
+			else begin
+				if(cdi.stackop != ST_SKIP) sp <= sp_next;
+				if(sp[0]) st_lo <= r1; 
+			end
+	end
+
+	// ======================== //
+	// 			Memory 			//
+	// ======================== //
+
+	word mem_wr_hi; // High byte of memory store
+	always_ff@(posedge clk) begin
+			if(rst) mem_wr_hi <= '0; 
+			else if(cdi.selo == SO_MEMH) mem_wr_hi <= r1;
+	end
+
+	assign mem_wr[7:0] = r1;
+	assign mem_wr[15:8] = (cdi.stackop == ST_SUB) ? st_wr : mem_wr_hi;
+	assign mem_addr = (cdi.stackop != ST_SKIP) ? sp_addr : imm;
+
+	// COM Write
+	assign com_wr = (cdi.selo == SO_COM) ? r1 : '0;
+	assign com_addr = imm[7:0];
+
 	assign srcA = r1;
 	always_comb begin
 		case(cdi.selb)
@@ -86,7 +136,8 @@ module datapath8(
 		endcase
 
 		case(cdi.selr)
-			SR_MEML: reg_wr = mem_rd[7:0];
+			SR_REG : reg_wr = r2;
+			SR_MEML: reg_wr = (cdi.stackop == ST_ADD) ? st_rd : mem_rd[7:0];
 			SR_MEMH: reg_wr = mem_rd[15:8];
 			SR_ALUL: reg_wr = alu_rlo;
 			SR_ALUH: reg_wr = alu_rhi;

+ 20 - 2
src/risc/general.sv

@@ -72,8 +72,17 @@ package risc8_pkg;
 		SB_IMM = 2'b11
 	} e_selb;
 
+	typedef enum logic [1:0] {
+		SO_NONE= 2'bxx,
+		SO_COM = 2'b00,
+		SO_MEMH= 2'b01,
+		SO_MEML= 2'b10
+		//SO_= 2'b11
+	} e_selo;
+
 	typedef enum logic [2:0] {
 		SR_NONE= 3'bxxx,
+		SR_REG = 3'b000,
 		SR_MEML= 3'b001,
 		SR_MEMH= 3'b010,
 		SR_ALUL= 3'b011,
@@ -90,6 +99,13 @@ package risc8_pkg;
 		REG3  = 2'b11
 	} e_reg_addr;
 
+	typedef enum logic [1:0] {
+		ST_SKIP= 2'b00,
+		ST_ADD = 2'b01,
+		ST_SUB = 2'b10,
+		ST_3   = 2'b11
+	} e_stackop;
+
 endpackage
 
 interface risc8_cdi;  // Control Datapath interface	
@@ -100,6 +116,8 @@ interface risc8_cdi;  // Control Datapath interface
 	e_alu_op alu_op;
 	logic sign, alu_not;
 	e_selb selb;
+	e_selo selo;
+	e_stackop stackop;
 	logic [2:0] alu_comp;
 	
 	// Register
@@ -109,13 +127,13 @@ interface risc8_cdi;  // Control Datapath interface
 	logic [1:0] isize; // instruction size between 1 and 4
 	
 	modport datapath(
-		input alu_op, selb, sign, alu_not,
+		input alu_op, selb, sign, alu_not, selo, stackop,
 		output alu_comp,
 		input a1, a2, a3, rw_en, selr, mem_h, isize
 	);
 	
 	modport control(
-		output alu_op, selb, sign, alu_not,
+		output alu_op, selb, sign, alu_not, selo, stackop,
 		input alu_comp,
 		output a1, a2, a3, rw_en, selr, mem_h, isize
 	);

+ 28 - 28
tools/asm_compiler.py

@@ -5,46 +5,47 @@ import argparse
 from os import path
 
 
-def decode_byte(val: str):
+def decode_bytes(val: str):
     try:
         if val.endswith('h'):
-            return int(val[:-1], 16)
+            return [int(val[i:i+2], 16) for i in range(0, len(val)-1, 2)]
         if val.startswith('0x'):
-            return int(val[2:], 16)
+            return [int(val[i:i+2], 16) for i in range(2, len(val), 2)]
         if val.startswith('b'):
-            return int(val.replace('_', '')[1:], 2)
+            val = val.replace('_', '')[1:]
+            return [int(val[i:i+8], 2) for i in range(0, len(val), 8)]
     except ValueError:
         raise ValueError(f"Invalid binary '{val}'")
     if val.isdigit():
         i = int(val)
         if i > 255 or i < 0:
             raise ValueError(f"Invalid binary '{val}', unsigned int out of bounds")
-        return i
+        return [i]
     if (val.startswith('+') or val.startswith('-')) and val[1:].isdigit():
         i = int(val)
         if i > 127 or i < -128:
             raise ValueError(f"Invalid binary '{val}', signed int out of bounds")
         if i < 0:  # convert to unsigned
             i += 2 ** 8
-        return i
+        return [i]
     if len(val) == 3 and ((val[0] == "'" and val[2] == "'") or (val[0] == '"' and val[2] == '"')):
-        return ord(val[1])
+        return [ord(val[1])]
     raise ValueError(f"Invalid binary '{val}'")
 
 
 def is_reg(r):
     if r.startswith('$'):
         r = r[1:]
-    if r.isnumeric() and 0 <= int(r) <= 3:
-        return True
-    elif len(r) == 2 and (r == 'ra' or r == 'rb' or r == 'rc' or r == 're'):
+        if r.isnumeric() and 0 <= int(r) <= 3:
+            return True
+    elif len(r) == 2 and r[0] == 'r' and r[1] in {'0', '1', '2', '3', 'a', 'b', 'c', 'e'}:
         return True
     return False
 
 
 def decode_reg(r):
-    if r.isnumeric():
-        r = int(r)
+    if r.startswith('$') and r[1:].isnumeric():
+        r = int(r[1:])
     if isinstance(r, int):
         if 0 <= r <= 3:
             return r
@@ -52,13 +53,13 @@ def decode_reg(r):
     rl = r.lower()
     if rl.startswith('$'):
         rl = rl[1:]
-    if rl == 'ra':
+    if rl == 'ra' or rl == 'r0':
         return 0
-    if rl == 'rb':
+    if rl == 'rb' or rl == 'r1':
         return 1
-    if rl == 'rc':
+    if rl == 'rc' or rl == 'r2':
         return 2
-    if rl == 're':
+    if rl == 're' or rl == 'r3':
         return 3
     raise ValueError(f"Invalid register name '{r}'")
 
@@ -111,16 +112,15 @@ def assemble(file):
         elif instr == 'XOR':
             iname = 'XOR'
             inibb = 5
-        elif instr == 'GT' or instr == 'GRT':
-            iname = 'GT'
+        elif instr == 'MUL':
+            iname = 'MUL'
             inibb = 6
-        elif instr == 'EX' or instr == 'EXT':
-            iname = 'EXT'
-            inibb = 7
-        elif instr == 'SHFL':
-            iname = 'SHTL'
+        elif instr == 'DIV':
+            iname = 'DIV'
             inibb = 7
-            ops.append(0)
+        elif instr == 'SLL':
+            iname = 'SLL'
+            inibb = 9
         elif instr == 'SHFR':
             iname = 'SHTR'
             inibb = 7
@@ -154,7 +154,7 @@ def assemble(file):
         else:
             if len(ops) == 1:
                 try:
-                    odata.append(decode_byte(ops[0]))
+                    odata += decode_bytes(ops[0])
                     continue
                 except ValueError:
                     pass
@@ -169,7 +169,7 @@ def assemble(file):
             if iname == 'JUMP':
                 odata.append(inibb << 4)
                 try:
-                    odata.append(decode_byte(ops[1]))
+                    odata += decode_bytes(ops[1])
                 except ValueError:
                     if not ops[1].isalnum():
                         print(f"{file}:{lnum}: Invalid pointer reference '{ops[1]}'")
@@ -184,7 +184,7 @@ def assemble(file):
 
             rd = decode_reg(ops[1])
             if iname == 'COPY' and not is_reg(ops[2]):
-                imm = decode_byte(ops[2])
+                imm = decode_bytes(ops[2])[0]
                 odata.append((inibb << 4) | (rd << 2) | rd)
                 odata.append(int(imm))
                 continue
@@ -202,7 +202,7 @@ def assemble(file):
             odata.append((inibb << 4) | (rd << 2) | rs)
             if iname == 'JEQ':
                 try:
-                    odata.append(decode_byte(ops[3]))
+                    odata += decode_bytes(ops[3])
                 except ValueError:
                     if not ops[3].isalnum():
                         print(f"{file}:{lnum}: Invalid pointer reference '{ops[3]}'")