mirror of
https://github.com/sxpert/hp-saturn
synced 2025-01-31 19:57:50 +01:00
finally, something that is synthesizable !
This commit is contained in:
parent
9ecdc1799b
commit
d4c67cf8fc
2 changed files with 98 additions and 48 deletions
140
saturn-decoder.v
140
saturn-decoder.v
|
@ -13,6 +13,7 @@ module saturn_decoder(
|
|||
i_en_exec,
|
||||
// i_stalled,
|
||||
i_nibble,
|
||||
o_pc,
|
||||
o_dec_error);
|
||||
|
||||
/*
|
||||
|
@ -27,19 +28,23 @@ input wire i_en_exec;
|
|||
// input wire i_stalled;
|
||||
input wire [3:0] i_nibble;
|
||||
|
||||
output wire [19:0] o_pc;
|
||||
output reg o_dec_error;
|
||||
|
||||
/*
|
||||
* state registers
|
||||
*/
|
||||
|
||||
reg continue;
|
||||
wire instr_start;
|
||||
reg ins_decoded;
|
||||
reg [31:0] instr_ctr;
|
||||
|
||||
initial begin
|
||||
continue = 0;
|
||||
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"},
|
||||
|
@ -50,53 +55,71 @@ initial begin
|
|||
`endif
|
||||
end
|
||||
|
||||
assign o_pc = PC;
|
||||
|
||||
/*
|
||||
* debugger
|
||||
*
|
||||
*/
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_en_dbg) begin
|
||||
if (!i_reset && i_en_dbg)
|
||||
if (!continue&ins_decoded) begin
|
||||
`ifdef SIM
|
||||
$display("blk0x %b | ins_rtn %b | xm %b | carry %b", block_0x, ins_rtn, xm, carry);
|
||||
$write("%5h ", ins_addr);
|
||||
if (ins_rtn) begin
|
||||
$write("RTN");
|
||||
if (set_xm) $write("SXM");
|
||||
if (set_carry) $write("%sC", carry_val?"S":"C");
|
||||
$display("");
|
||||
end
|
||||
`endif
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
/*
|
||||
* handle the fist nibble decoding
|
||||
/******************************************************************************
|
||||
*
|
||||
* handle decoding of the fist nibble
|
||||
* that's pretty simple though, will get tougher later on :-)
|
||||
*/
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
reg block_0x;
|
||||
reg [19:0] ins_addr;
|
||||
reg inc_pc_x;
|
||||
reg continue_x;
|
||||
reg block_0x;
|
||||
|
||||
assign instr_start = ~continue || i_reset;
|
||||
wire continue;
|
||||
|
||||
assign continue = continue_x || continue_0x;
|
||||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset) begin
|
||||
inc_pc_x <= 0;
|
||||
continue_x <= 0;
|
||||
block_0x <= 0;
|
||||
o_dec_error <= 0;
|
||||
end else begin
|
||||
if (i_en_dec)
|
||||
if (instr_start) begin
|
||||
`ifdef SIM
|
||||
$display("%d | %b | %b | fn %h", i_cycles, i_en_dec, i_en_exec, i_nibble);
|
||||
`endif
|
||||
continue <= 1;
|
||||
if (!continue) begin
|
||||
continue_x <= 1;
|
||||
ins_decoded <= 0;
|
||||
// store the address where the instruction starts
|
||||
ins_addr <= PC;
|
||||
inc_pc_x <= 1;
|
||||
// assign block regs
|
||||
case (i_nibble)
|
||||
4'h0: block_0x <= 1;
|
||||
default: begin
|
||||
`ifdef SIM
|
||||
$display("first_nibble: nibble %h not handled", i_nibble);
|
||||
$display("new_instruction: nibble %h not handled", i_nibble);
|
||||
`endif
|
||||
o_dec_error <= 1;
|
||||
end
|
||||
endcase
|
||||
end else begin
|
||||
`ifdef SIM
|
||||
$display("%d | first_nibble: clear block_0x", i_cycles);
|
||||
`endif
|
||||
inc_pc_x <= 0;
|
||||
continue_x <= 0;
|
||||
block_0x <= 0;
|
||||
end
|
||||
end
|
||||
|
@ -111,7 +134,10 @@ end
|
|||
* 02 RTNSC
|
||||
* 03 RTNCC
|
||||
*
|
||||
*/
|
||||
*****************************************************************************/
|
||||
|
||||
reg inc_pc_0x;
|
||||
reg continue_0x;
|
||||
|
||||
reg ins_rtn;
|
||||
|
||||
|
@ -121,17 +147,16 @@ reg carry_val;
|
|||
|
||||
always @(posedge i_clk) begin
|
||||
if (i_reset) begin
|
||||
ins_rtn <= 0;
|
||||
set_xm <= 0;
|
||||
set_carry <= 0;
|
||||
carry_val <= 0;
|
||||
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
|
||||
`ifdef SIM
|
||||
$display("%d | block_0x:", i_cycles);
|
||||
`endif
|
||||
block_0x <= 0;
|
||||
inc_pc_0x <= 1;
|
||||
case (i_nibble)
|
||||
4'h0, 4'h1, 4'h2, 4'h3: ins_rtn <= 1;
|
||||
default: begin
|
||||
|
@ -144,15 +169,16 @@ always @(posedge i_clk) begin
|
|||
set_xm <= (i_nibble == 4'h0);
|
||||
set_carry <= (i_nibble[3:1] == 1);
|
||||
carry_val <= (i_nibble[1] && i_nibble[0]);
|
||||
continue <= (i_nibble == 4'hE);
|
||||
continue_0x <= (i_nibble == 4'hE);
|
||||
ins_decoded <= (i_nibble != 4'hE);
|
||||
end else begin
|
||||
`ifdef SIM
|
||||
$display("%d | block_0x: clearing rtn, xm, sc, cv", i_cycles);
|
||||
`endif
|
||||
ins_rtn <= 0;
|
||||
set_xm <= 0;
|
||||
set_carry <= 0;
|
||||
carry_val <= 0;
|
||||
inc_pc_0x <= 0;
|
||||
continue_0x <= 0;
|
||||
// cleanup
|
||||
ins_rtn <= 0;
|
||||
set_xm <= 0;
|
||||
set_carry <= 0;
|
||||
carry_val <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -166,20 +192,40 @@ end
|
|||
*
|
||||
*****************************************************************************/
|
||||
|
||||
reg xm;
|
||||
reg carry;
|
||||
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)
|
||||
set_xm <= 0;
|
||||
else
|
||||
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
|
||||
`ifdef SIM
|
||||
$display("RTN (XM: %b SC %b CV %b)", set_xm, set_carry, carry_val);
|
||||
`endif
|
||||
xm <= set_xm?1:xm;
|
||||
carry <= set_carry?carry_val:carry;
|
||||
HST[0] <= set_xm?1:HST[0];
|
||||
CARRY <= set_carry?carry_val:CARRY;
|
||||
// do RTN things
|
||||
end
|
||||
end
|
||||
|
|
|
@ -57,6 +57,7 @@ reg [31:0] max_cycle;
|
|||
|
||||
// state machine stuff
|
||||
wire halt;
|
||||
wire [19:0] reg_pc;
|
||||
wire dec_error;
|
||||
|
||||
// hp48_bus bus_ctrl (
|
||||
|
@ -78,6 +79,7 @@ saturn_decoder i_decoder (
|
|||
.i_en_exec (en_inst_exec),
|
||||
// .i_stalled (stalled),
|
||||
.i_nibble (nibble_in),
|
||||
.o_pc (reg_pc),
|
||||
.o_dec_error (dec_error)
|
||||
);
|
||||
|
||||
|
@ -139,7 +141,9 @@ always @(posedge clk) begin
|
|||
clock_end <= 0;
|
||||
cycle_ctr <= ~0;
|
||||
max_cycle <= 50;
|
||||
|
||||
`ifndef SIM
|
||||
led[7:0] <= reg_pc[7:0];
|
||||
`endif
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue