diff --git a/.gitignore b/.gitignore index 9482fd8..00ac16c 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ obj_dir/Vsaturn_core_classes.mk saturn_core.ICE40.json blinky.pcf demo.blif +history.txt \ No newline at end of file diff --git a/saturn-decoder.v b/saturn-decoder.v index 21ac3b7..c59e252 100644 --- a/saturn-decoder.v +++ b/saturn-decoder.v @@ -10,10 +10,10 @@ module saturn_decoder( i_cycles, i_en_dbg, i_en_dec, - i_en_exec, // i_stalled, + i_pc, i_nibble, - o_pc, + o_inc_pc, o_dec_error); /* @@ -24,11 +24,11 @@ input wire i_reset; input wire [31:0] i_cycles; input wire i_en_dbg; input wire i_en_dec; -input wire i_en_exec; // input wire i_stalled; +input wire [19:0] i_pc; input wire [3:0] i_nibble; -output wire [19:0] o_pc; +output reg o_inc_pc; output reg o_dec_error; /* @@ -39,24 +39,16 @@ reg ins_decoded; reg [31:0] instr_ctr; initial begin - o_dec_error = 0; - ins_decoded = 0; - // initialize all registers - HST = 0; - CARRY = 0; - PC = 0; `ifdef SIM // $monitor({"i_clk %b | i_reset %b | i_cycles %d | i_en_dec %b | i_en_exec %b |", // " continue %b | instr_start %b | i_nibble %h"}, // i_clk, i_reset, i_cycles, i_en_dec, i_en_exec, continue, // instr_start, i_nibble); - // $monitor("i_en_dec %b | i_en_exec %b | i_cycles %d | nb %h | fn %b | cont %b | b0x %b | rtn %b | sxm %b | sc %b | cv %b", - // i_en_dec, i_en_exec, i_cycles, i_nibble, instr_start, continue, block_0x, ins_rtn, set_xm, set_carry, carry_val); + // $monitor("i_en_dec %b | i_cycles %d | nb %h | cont %b | b0x %b | rtn %b | sxm %b | sc %b | cv %b", + // i_en_dec, i_cycles, i_nibble, continue, block_0x, ins_rtn, set_xm, set_carry, carry_val); `endif end -assign o_pc = PC; - /* * debugger * @@ -73,6 +65,12 @@ always @(posedge i_clk) begin if (set_carry) $write("%sC", carry_val?"S":"C"); $display(""); end + if (ins_set_mode) begin + $display("SET%s", mode_dec?"DEC":"HEX"); + end + if (ins_rstk_c) begin + $display("%s", direction?"C=RSTK":"RSTK=C"); + end `endif end end @@ -84,29 +82,71 @@ end * *****************************************************************************/ +// general variables reg [19:0] ins_addr; -reg inc_pc_x; -reg continue_x; +reg continue; + reg block_0x; -wire continue; +// generic +reg direction; -assign continue = continue_x || continue_0x; +// rtn specific +reg ins_rtn; +reg set_xm; +reg set_carry; +reg carry_val; + +// setdec/hex +reg ins_set_mode; +reg mode_dec; + +// rstk and c +reg ins_rstk_c; always @(posedge i_clk) begin if (i_reset) begin - inc_pc_x <= 0; - continue_x <= 0; - block_0x <= 0; - o_dec_error <= 0; + continue <= 0; + o_inc_pc <= 1; + o_dec_error <= 0; + ins_decoded <= 0; + end else begin - if (i_en_dec) + if (i_en_dec) begin + + /* + * stuff that is always done + */ + o_inc_pc <= 1; // may be set to 0 later + + /* + * cleanup + */ if (!continue) begin - continue_x <= 1; - ins_decoded <= 0; + continue <= 1; + ins_decoded <= 0; // store the address where the instruction starts - ins_addr <= PC; - inc_pc_x <= 1; + ins_addr <= i_pc; + + // cleanup + direction <= 0; + + ins_rtn <= 0; + set_xm <= 0; + set_carry <= 0; + carry_val <= 0; + + ins_set_mode <= 0; + mode_dec <= 0; + + ins_rstk_c <= 0; + end + + /* + * x first nibble + */ + + if (!continue) begin // assign block regs case (i_nibble) 4'h0: block_0x <= 1; @@ -117,48 +157,35 @@ always @(posedge i_clk) begin o_dec_error <= 1; end endcase - end else begin - inc_pc_x <= 0; - continue_x <= 0; - block_0x <= 0; end - end -end -/****************************************************************************** - * - * 0x - * - * 00 RTNSXM - * 01 RTN - * 02 RTNSC - * 03 RTNCC - * - *****************************************************************************/ + /****************************************************************************** + * + * 0x + * + * 00 RTNSXM + * 01 RTN + * 02 RTNSC + * 03 RTNCC + * + *****************************************************************************/ -reg inc_pc_0x; -reg continue_0x; - -reg ins_rtn; - -reg set_xm; -reg set_carry; -reg carry_val; - -always @(posedge i_clk) begin - if (i_reset) begin - inc_pc_0x <= 0; - continue_0x <= 0; - ins_rtn <= 0; - set_xm <= 0; - set_carry <= 0; - carry_val <= 0; - end else begin - if (i_en_dec) if (continue && block_0x) begin - inc_pc_0x <= 1; case (i_nibble) - 4'h0, 4'h1, 4'h2, 4'h3: ins_rtn <= 1; + 4'h0, 4'h1, 4'h2, 4'h3: begin + ins_rtn <= 1; + set_xm <= (i_nibble == 4'h0); + set_carry <= (i_nibble[3:1] == 1); + carry_val <= (i_nibble[1] && i_nibble[0]); + end + 4'h4, 4'h5 : begin + ins_set_mode <= 1; + mode_dec <= (i_nibble[0]); + end + 4'h6, 6'h7 : begin + ins_rstk_c <= 1; + direction <= (i_nibble[0]); + end default: begin `ifdef SIM $display("block_0x: nibble %h not handled", i_nibble); @@ -166,68 +193,15 @@ always @(posedge i_clk) begin o_dec_error <= 1; end endcase - set_xm <= (i_nibble == 4'h0); - set_carry <= (i_nibble[3:1] == 1); - carry_val <= (i_nibble[1] && i_nibble[0]); - continue_0x <= (i_nibble == 4'hE); + continue <= (i_nibble == 4'hE); ins_decoded <= (i_nibble != 4'hE); - end else begin - inc_pc_0x <= 0; - continue_0x <= 0; - // cleanup - ins_rtn <= 0; - set_xm <= 0; - set_carry <= 0; - carry_val <= 0; - end + end + + + + end -end - - - - -/****************************************************************************** - * - * execute things - * - *****************************************************************************/ - -reg [3:0] HST; // hardware satus flags |MP|SR|SB|XM| -reg CARRY; // public carry -reg DEC; // decimal mode - -reg [19:0] PC; - -/**** - * PC handler - * - */ -wire inc_pc; - -assign inc_pc = inc_pc_x || inc_pc_0x; - -always @(posedge i_clk) begin - if (!i_reset) - if(i_en_exec) - if (inc_pc) begin - PC <= PC + 1; - end -end - - -/**** - * RTN[SXM,,SC,CC] - * - */ - -always @(posedge i_clk) begin - if (!i_reset) - if (i_en_exec) - if (ins_rtn) begin - HST[0] <= set_xm?1:HST[0]; - CARRY <= set_carry?carry_val:CARRY; - // do RTN things - end + end end diff --git a/saturn_core.v b/saturn_core.v index 3734ef8..4e9ada1 100644 --- a/saturn_core.v +++ b/saturn_core.v @@ -57,7 +57,7 @@ reg [31:0] max_cycle; // state machine stuff wire halt; -wire [19:0] reg_pc; +wire inc_pc; wire dec_error; // hp48_bus bus_ctrl ( @@ -76,15 +76,19 @@ saturn_decoder i_decoder ( .i_cycles (cycle_ctr), .i_en_dbg (en_debugger), .i_en_dec (en_inst_dec), - .i_en_exec (en_inst_exec), + .i_pc (reg_pc), // .i_stalled (stalled), .i_nibble (nibble_in), - .o_pc (reg_pc), + .o_inc_pc (inc_pc), .o_dec_error (dec_error) ); + +reg [3:0] rom [0:1024]; + initial begin + $readmemh( "testrom.hex", rom); clk_phase = 0; en_debugger = 0; // phase 0 en_bus_send = 0; // phase 0 @@ -96,6 +100,7 @@ initial en_inst_exec = 0; // phase 3 clock_end = 0; cycle_ctr = 0; + reg_pc = 0; `ifdef DEBUG_CLOCKS $monitor("RST %b | CLK %b | CLKP %d | CYCL %d | eRST %b | eDBG %b | eBSND %b | eBRECV %b | eAPR %b | eACALC %b | eINDC %b | eASAVE %b | eINDX %b", @@ -151,29 +156,26 @@ end // if (en_debugger) // $display(cycle_ctr); -reg [3:0] nibble_in; +reg [3:0] nibble_in; +reg [19:0] reg_pc; always @(posedge clk) - if (en_bus_recv) - case (cycle_ctr) - // RTNSXM - 0: nibble_in <= 0; - 1: nibble_in <= 0; - // RTN - 2: nibble_in <= 0; - 3: nibble_in <= 1; - // RTNSC - 4: nibble_in <= 0; - 5: nibble_in <= 2; - // RTNCC - 6: nibble_in <= 0; - 7: nibble_in <= 3; - // SETHEX - 8: nibble_in <= 0; - 9: nibble_in <= 4; - // END - 50: clock_end <= 1; - endcase + if (reset) + reg_pc <= ~0; + else begin + if (en_bus_send) begin + if (inc_pc) + reg_pc <= reg_pc + 1; + else + $display("not incrementing PC"); + end + if (en_bus_recv) begin +`ifdef SIM + $display("%5h %h", reg_pc, rom[reg_pc]); +`endif + nibble_in <= rom[reg_pc]; + end + end assign halt = clock_end || dec_error; diff --git a/testrom.hex b/testrom.hex new file mode 100644 index 0000000..c7becef --- /dev/null +++ b/testrom.hex @@ -0,0 +1,10 @@ +0 0 // RTNSXM +0 1 // RTN +0 2 // RTNSC +0 3 // RTNCC +0 4 // SETHEX +0 5 // SETDEC +0 6 // RSTK=C +0 7 // C=RSTK + +F // end \ No newline at end of file