mirror of
https://github.com/sxpert/hp-saturn
synced 2025-01-31 19:57:50 +01:00
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:
parent
d4c67cf8fc
commit
c7cc7f417b
4 changed files with 135 additions and 148 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -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
|
222
saturn-decoder.v
222
saturn-decoder.v
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
10
testrom.hex
Normal 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
|
Loading…
Add table
Reference in a new issue