refactor as it was getting too complicated

secret seems to limit the levels of imbricated ifs...
added
SETHEX
SETDEC
RSTK=C
C=RSTK
This commit is contained in:
Raphael Jacquot 2019-02-12 07:48:25 +01:00
parent d4c67cf8fc
commit c7cc7f417b
4 changed files with 135 additions and 148 deletions

1
.gitignore vendored
View file

@ -9,3 +9,4 @@ obj_dir/Vsaturn_core_classes.mk
saturn_core.ICE40.json saturn_core.ICE40.json
blinky.pcf blinky.pcf
demo.blif demo.blif
history.txt

View file

@ -10,10 +10,10 @@ module saturn_decoder(
i_cycles, i_cycles,
i_en_dbg, i_en_dbg,
i_en_dec, i_en_dec,
i_en_exec,
// i_stalled, // i_stalled,
i_pc,
i_nibble, i_nibble,
o_pc, o_inc_pc,
o_dec_error); o_dec_error);
/* /*
@ -24,11 +24,11 @@ input wire i_reset;
input wire [31:0] i_cycles; input wire [31:0] i_cycles;
input wire i_en_dbg; input wire i_en_dbg;
input wire i_en_dec; input wire i_en_dec;
input wire i_en_exec;
// input wire i_stalled; // input wire i_stalled;
input wire [19:0] i_pc;
input wire [3:0] i_nibble; input wire [3:0] i_nibble;
output wire [19:0] o_pc; output reg o_inc_pc;
output reg o_dec_error; output reg o_dec_error;
/* /*
@ -39,24 +39,16 @@ reg ins_decoded;
reg [31:0] instr_ctr; reg [31:0] instr_ctr;
initial begin initial begin
o_dec_error = 0;
ins_decoded = 0;
// initialize all registers
HST = 0;
CARRY = 0;
PC = 0;
`ifdef SIM `ifdef SIM
// $monitor({"i_clk %b | i_reset %b | i_cycles %d | i_en_dec %b | i_en_exec %b |", // $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"}, // " continue %b | instr_start %b | i_nibble %h"},
// i_clk, i_reset, i_cycles, i_en_dec, i_en_exec, continue, // i_clk, i_reset, i_cycles, i_en_dec, i_en_exec, continue,
// instr_start, i_nibble); // 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", // $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_en_exec, i_cycles, i_nibble, instr_start, continue, block_0x, ins_rtn, set_xm, set_carry, carry_val); // i_en_dec, i_cycles, i_nibble, continue, block_0x, ins_rtn, set_xm, set_carry, carry_val);
`endif `endif
end end
assign o_pc = PC;
/* /*
* debugger * debugger
* *
@ -73,6 +65,12 @@ always @(posedge i_clk) begin
if (set_carry) $write("%sC", carry_val?"S":"C"); if (set_carry) $write("%sC", carry_val?"S":"C");
$display(""); $display("");
end 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 `endif
end end
end end
@ -84,29 +82,71 @@ end
* *
*****************************************************************************/ *****************************************************************************/
// general variables
reg [19:0] ins_addr; reg [19:0] ins_addr;
reg inc_pc_x; reg continue;
reg continue_x;
reg block_0x; 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 always @(posedge i_clk) begin
if (i_reset) begin if (i_reset) begin
inc_pc_x <= 0; continue <= 0;
continue_x <= 0; o_inc_pc <= 1;
block_0x <= 0; o_dec_error <= 0;
o_dec_error <= 0; ins_decoded <= 0;
end else begin 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 if (!continue) begin
continue_x <= 1; continue <= 1;
ins_decoded <= 0; ins_decoded <= 0;
// store the address where the instruction starts // store the address where the instruction starts
ins_addr <= PC; ins_addr <= i_pc;
inc_pc_x <= 1;
// 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 // assign block regs
case (i_nibble) case (i_nibble)
4'h0: block_0x <= 1; 4'h0: block_0x <= 1;
@ -117,48 +157,35 @@ always @(posedge i_clk) begin
o_dec_error <= 1; o_dec_error <= 1;
end end
endcase endcase
end else begin
inc_pc_x <= 0;
continue_x <= 0;
block_0x <= 0;
end end
end
end
/****************************************************************************** /******************************************************************************
* *
* 0x * 0x
* *
* 00 RTNSXM * 00 RTNSXM
* 01 RTN * 01 RTN
* 02 RTNSC * 02 RTNSC
* 03 RTNCC * 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 if (continue && block_0x) begin
inc_pc_0x <= 1;
case (i_nibble) 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 default: begin
`ifdef SIM `ifdef SIM
$display("block_0x: nibble %h not handled", i_nibble); $display("block_0x: nibble %h not handled", i_nibble);
@ -166,68 +193,15 @@ always @(posedge i_clk) begin
o_dec_error <= 1; o_dec_error <= 1;
end end
endcase endcase
set_xm <= (i_nibble == 4'h0); continue <= (i_nibble == 4'hE);
set_carry <= (i_nibble[3:1] == 1);
carry_val <= (i_nibble[1] && i_nibble[0]);
continue_0x <= (i_nibble == 4'hE);
ins_decoded <= (i_nibble != 4'hE); ins_decoded <= (i_nibble != 4'hE);
end else begin end
inc_pc_0x <= 0;
continue_0x <= 0;
// cleanup
ins_rtn <= 0;
set_xm <= 0;
set_carry <= 0;
carry_val <= 0;
end
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

View file

@ -57,7 +57,7 @@ reg [31:0] max_cycle;
// state machine stuff // state machine stuff
wire halt; wire halt;
wire [19:0] reg_pc; wire inc_pc;
wire dec_error; wire dec_error;
// hp48_bus bus_ctrl ( // hp48_bus bus_ctrl (
@ -76,15 +76,19 @@ saturn_decoder i_decoder (
.i_cycles (cycle_ctr), .i_cycles (cycle_ctr),
.i_en_dbg (en_debugger), .i_en_dbg (en_debugger),
.i_en_dec (en_inst_dec), .i_en_dec (en_inst_dec),
.i_en_exec (en_inst_exec), .i_pc (reg_pc),
// .i_stalled (stalled), // .i_stalled (stalled),
.i_nibble (nibble_in), .i_nibble (nibble_in),
.o_pc (reg_pc), .o_inc_pc (inc_pc),
.o_dec_error (dec_error) .o_dec_error (dec_error)
); );
reg [3:0] rom [0:1024];
initial initial
begin begin
$readmemh( "testrom.hex", rom);
clk_phase = 0; clk_phase = 0;
en_debugger = 0; // phase 0 en_debugger = 0; // phase 0
en_bus_send = 0; // phase 0 en_bus_send = 0; // phase 0
@ -96,6 +100,7 @@ initial
en_inst_exec = 0; // phase 3 en_inst_exec = 0; // phase 3
clock_end = 0; clock_end = 0;
cycle_ctr = 0; cycle_ctr = 0;
reg_pc = 0;
`ifdef DEBUG_CLOCKS `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", $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) // if (en_debugger)
// $display(cycle_ctr); // $display(cycle_ctr);
reg [3:0] nibble_in; reg [3:0] nibble_in;
reg [19:0] reg_pc;
always @(posedge clk) always @(posedge clk)
if (en_bus_recv) if (reset)
case (cycle_ctr) reg_pc <= ~0;
// RTNSXM else begin
0: nibble_in <= 0; if (en_bus_send) begin
1: nibble_in <= 0; if (inc_pc)
// RTN reg_pc <= reg_pc + 1;
2: nibble_in <= 0; else
3: nibble_in <= 1; $display("not incrementing PC");
// RTNSC end
4: nibble_in <= 0; if (en_bus_recv) begin
5: nibble_in <= 2; `ifdef SIM
// RTNCC $display("%5h %h", reg_pc, rom[reg_pc]);
6: nibble_in <= 0; `endif
7: nibble_in <= 3; nibble_in <= rom[reg_pc];
// SETHEX end
8: nibble_in <= 0; end
9: nibble_in <= 4;
// END
50: clock_end <= 1;
endcase
assign halt = clock_end || dec_error; assign halt = clock_end || dec_error;

10
testrom.hex Normal file
View file

@ -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