finally, something that is synthesizable !

This commit is contained in:
Raphael Jacquot 2019-02-12 00:07:12 +01:00
parent 9ecdc1799b
commit d4c67cf8fc
2 changed files with 98 additions and 48 deletions

View file

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

View file

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