mirror of
https://github.com/sxpert/hp-saturn
synced 2025-01-20 10:26:31 +01:00
initialize all registers, implement jmp_rel2
cleanup the controller some more prepare the core to be rewired add support for block Bx
This commit is contained in:
parent
4418ed5824
commit
4cce55e4ba
9 changed files with 538 additions and 254 deletions
277
saturn_alu.v
277
saturn_alu.v
|
@ -61,6 +61,7 @@ module saturn_alu (
|
||||||
i_mode_dec,
|
i_mode_dec,
|
||||||
i_set_xm,
|
i_set_xm,
|
||||||
i_set_carry,
|
i_set_carry,
|
||||||
|
i_test_carry,
|
||||||
i_carry_val,
|
i_carry_val,
|
||||||
|
|
||||||
o_reg_p,
|
o_reg_p,
|
||||||
|
@ -123,6 +124,7 @@ input wire [0:0] i_ins_unconfig;
|
||||||
input wire [0:0] i_mode_dec;
|
input wire [0:0] i_mode_dec;
|
||||||
input wire [0:0] i_set_xm;
|
input wire [0:0] i_set_xm;
|
||||||
input wire [0:0] i_set_carry;
|
input wire [0:0] i_set_carry;
|
||||||
|
input wire [0:0] i_test_carry;
|
||||||
input wire [0:0] i_carry_val;
|
input wire [0:0] i_carry_val;
|
||||||
|
|
||||||
output wire [3:0] o_reg_p;
|
output wire [3:0] o_reg_p;
|
||||||
|
@ -197,58 +199,6 @@ reg [19:0] RSTK[0:7];
|
||||||
|
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
// alu internal control bits
|
|
||||||
alu_op = 0;
|
|
||||||
reg_dest = 0;
|
|
||||||
reg_src1 = 0;
|
|
||||||
reg_src2 = 0;
|
|
||||||
f_first = 0;
|
|
||||||
f_cur = 0;
|
|
||||||
f_last = 0;
|
|
||||||
|
|
||||||
alu_run = 0;
|
|
||||||
alu_done = 0;
|
|
||||||
|
|
||||||
p_src1 = 0;
|
|
||||||
p_src2 = 0;
|
|
||||||
p_carry = 0;
|
|
||||||
c_res1 = 0;
|
|
||||||
c_res2 = 0;
|
|
||||||
c_carry = 0;
|
|
||||||
is_zero = 0;
|
|
||||||
// o_alu_stall_dec = 0;
|
|
||||||
// processor registers
|
|
||||||
PC = 0;
|
|
||||||
|
|
||||||
// D0 = 0;
|
|
||||||
// D1 = 0;
|
|
||||||
|
|
||||||
// A = 0;
|
|
||||||
// B = 0;
|
|
||||||
// C = 0;
|
|
||||||
// D = 0;
|
|
||||||
|
|
||||||
// R0 = 0;
|
|
||||||
// R1 = 0;
|
|
||||||
// R2 = 0;
|
|
||||||
// R3 = 0;
|
|
||||||
// R4 = 0;
|
|
||||||
|
|
||||||
// CARRY = 0;
|
|
||||||
// DEC = 0;
|
|
||||||
// P = 0;
|
|
||||||
// HST = 0;
|
|
||||||
// ST = 0;
|
|
||||||
|
|
||||||
rstk_ptr = 0;
|
|
||||||
// RSTK[0] = 0;
|
|
||||||
// RSTK[1] = 0;
|
|
||||||
// RSTK[2] = 0;
|
|
||||||
// RSTK[3] = 0;
|
|
||||||
// RSTK[4] = 0;
|
|
||||||
// RSTK[5] = 0;
|
|
||||||
// RSTK[6] = 0;
|
|
||||||
// RSTK[7] = 0;
|
|
||||||
end
|
end
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -313,7 +263,7 @@ end
|
||||||
|
|
||||||
// the decoder may request the ALU to not stall it
|
// the decoder may request the ALU to not stall it
|
||||||
|
|
||||||
assign o_alu_stall_dec = (!no_extra_cycles) ||
|
assign o_alu_stall_dec = !no_extra_cycles || alu_initializing ||
|
||||||
(alu_run &&
|
(alu_run &&
|
||||||
(!i_alu_no_stall || alu_finish || alu_go_test || o_bus_dp_read));
|
(!i_alu_no_stall || alu_finish || alu_go_test || o_bus_dp_read));
|
||||||
|
|
||||||
|
@ -329,11 +279,11 @@ assign f_next = (f_cur + 1) & 4'hF;
|
||||||
* test things on alu_op
|
* test things on alu_op
|
||||||
*/
|
*/
|
||||||
|
|
||||||
wire is_alu_op_jump;
|
wire is_alu_op_unc_jump;
|
||||||
assign is_alu_op_jump = ((alu_op == `ALU_OP_JMP_REL3) ||
|
assign is_alu_op_unc_jump = ((alu_op == `ALU_OP_JMP_REL3) ||
|
||||||
(alu_op == `ALU_OP_JMP_REL4) ||
|
(alu_op == `ALU_OP_JMP_REL4) ||
|
||||||
(alu_op == `ALU_OP_JMP_ABS5) ||
|
(alu_op == `ALU_OP_JMP_ABS5) ||
|
||||||
i_ins_rtn);
|
i_ins_rtn);
|
||||||
wire is_alu_op_test;
|
wire is_alu_op_test;
|
||||||
assign is_alu_op_test = ((alu_op == `ALU_OP_TEST_EQ) ||
|
assign is_alu_op_test = ((alu_op == `ALU_OP_TEST_EQ) ||
|
||||||
(alu_op == `ALU_OP_TEST_NEQ));
|
(alu_op == `ALU_OP_TEST_NEQ));
|
||||||
|
@ -432,6 +382,15 @@ assign is_mem_xfer = is_mem_read || is_mem_write;
|
||||||
assign mem_reg = is_mem_read?i_reg_src1:i_reg_dest;
|
assign mem_reg = is_mem_read?i_reg_src1:i_reg_dest;
|
||||||
|
|
||||||
always @(posedge i_clk) begin
|
always @(posedge i_clk) begin
|
||||||
|
|
||||||
|
if (i_reset) begin
|
||||||
|
alu_op <= 0;
|
||||||
|
reg_dest <= 0;
|
||||||
|
reg_src1 <= 0;
|
||||||
|
reg_src2 <= 0;
|
||||||
|
f_last <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
// this happens in phase 3, right after the instruction decoder (in phase 2) is finished
|
// this happens in phase 3, right after the instruction decoder (in phase 2) is finished
|
||||||
if (do_alu_init) begin
|
if (do_alu_init) begin
|
||||||
|
|
||||||
|
@ -458,6 +417,16 @@ end
|
||||||
|
|
||||||
always @(posedge i_clk) begin
|
always @(posedge i_clk) begin
|
||||||
|
|
||||||
|
if (i_reset) begin
|
||||||
|
alu_run <= 0;
|
||||||
|
alu_done <= 0;
|
||||||
|
f_first <= 0;
|
||||||
|
f_cur <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (alu_initializing)
|
||||||
|
f_cur <= f_cur + 1;
|
||||||
|
|
||||||
if (do_alu_init) begin
|
if (do_alu_init) begin
|
||||||
// $display("------------------------------------------------- DO_ALU_INIT");
|
// $display("------------------------------------------------- DO_ALU_INIT");
|
||||||
alu_run <= 1;
|
alu_run <= 1;
|
||||||
|
@ -493,6 +462,14 @@ end
|
||||||
|
|
||||||
|
|
||||||
always @(posedge i_clk) begin
|
always @(posedge i_clk) begin
|
||||||
|
|
||||||
|
if (i_reset) begin
|
||||||
|
p_src1 <= 0;
|
||||||
|
p_src2 <= 0;
|
||||||
|
p_carry <= 0;
|
||||||
|
jump_bse <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
if (do_alu_prep) begin
|
if (do_alu_prep) begin
|
||||||
if (alu_debug) begin
|
if (alu_debug) begin
|
||||||
`ifdef SIM
|
`ifdef SIM
|
||||||
|
@ -511,9 +488,11 @@ always @(posedge i_clk) begin
|
||||||
`ALU_OP_RST_BIT,
|
`ALU_OP_RST_BIT,
|
||||||
`ALU_OP_SET_BIT,
|
`ALU_OP_SET_BIT,
|
||||||
`ALU_OP_2CMPL,
|
`ALU_OP_2CMPL,
|
||||||
|
`ALU_OP_DEC,
|
||||||
`ALU_OP_ADD,
|
`ALU_OP_ADD,
|
||||||
`ALU_OP_TEST_EQ,
|
`ALU_OP_TEST_EQ,
|
||||||
`ALU_OP_TEST_NEQ,
|
`ALU_OP_TEST_NEQ,
|
||||||
|
`ALU_OP_JMP_REL2,
|
||||||
`ALU_OP_JMP_REL3,
|
`ALU_OP_JMP_REL3,
|
||||||
`ALU_OP_JMP_REL4,
|
`ALU_OP_JMP_REL4,
|
||||||
`ALU_OP_JMP_ABS5,
|
`ALU_OP_JMP_ABS5,
|
||||||
|
@ -551,6 +530,8 @@ always @(posedge i_clk) begin
|
||||||
`ALU_OP_RST_BIT,
|
`ALU_OP_RST_BIT,
|
||||||
`ALU_OP_SET_BIT,
|
`ALU_OP_SET_BIT,
|
||||||
`ALU_OP_2CMPL,
|
`ALU_OP_2CMPL,
|
||||||
|
`ALU_OP_DEC,
|
||||||
|
`ALU_OP_JMP_REL2,
|
||||||
`ALU_OP_JMP_REL3,
|
`ALU_OP_JMP_REL3,
|
||||||
`ALU_OP_JMP_REL4,
|
`ALU_OP_JMP_REL4,
|
||||||
`ALU_OP_JMP_ABS5: begin end // no need for a 2nd operand
|
`ALU_OP_JMP_ABS5: begin end // no need for a 2nd operand
|
||||||
|
@ -584,13 +565,15 @@ always @(posedge i_clk) begin
|
||||||
// setup p_carry
|
// setup p_carry
|
||||||
// $display("fs %h | fs=0 %b | cc %b | npc %b", f_start, (f_start == 0), c_carry, (f_start == 0)?1'b1:c_carry);
|
// $display("fs %h | fs=0 %b | cc %b | npc %b", f_start, (f_start == 0), c_carry, (f_start == 0)?1'b1:c_carry);
|
||||||
case (alu_op)
|
case (alu_op)
|
||||||
`ALU_OP_2CMPL: p_carry <= alu_start?1'b1:c_carry;
|
`ALU_OP_2CMPL: p_carry <= alu_start?1'b1:c_carry;
|
||||||
`ALU_OP_ADD: p_carry <= alu_start?0:c_carry;
|
`ALU_OP_DEC: p_carry <= alu_start?1'b0:c_carry;
|
||||||
`ALU_OP_TEST_NEQ: p_carry <= alu_start?0:c_carry;
|
`ALU_OP_ADD: p_carry <= alu_start?1'b0:c_carry;
|
||||||
|
`ALU_OP_TEST_NEQ: p_carry <= alu_start?1'b0:c_carry;
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
// prepare jump base
|
// prepare jump base
|
||||||
case (alu_op)
|
case (alu_op)
|
||||||
|
`ALU_OP_JMP_REL2,
|
||||||
`ALU_OP_JMP_REL3,
|
`ALU_OP_JMP_REL3,
|
||||||
`ALU_OP_JMP_REL4:
|
`ALU_OP_JMP_REL4:
|
||||||
begin
|
begin
|
||||||
|
@ -609,7 +592,11 @@ end
|
||||||
always @(posedge i_clk) begin
|
always @(posedge i_clk) begin
|
||||||
|
|
||||||
if (i_reset) begin
|
if (i_reset) begin
|
||||||
c_carry <= 0;
|
c_res1 <= 0;
|
||||||
|
c_res2 <= 0;
|
||||||
|
c_carry <= 0;
|
||||||
|
is_zero <= 0;
|
||||||
|
jump_off <= 0;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (do_alu_calc) begin
|
if (do_alu_calc) begin
|
||||||
|
@ -622,13 +609,13 @@ always @(posedge i_clk) begin
|
||||||
alu_run, alu_done, o_alu_stall_dec, alu_op, f_first, f_cur, f_last, jump_bse, jump_off, jump_pc, alu_finish);
|
alu_run, alu_done, o_alu_stall_dec, alu_op, f_first, f_cur, f_last, jump_bse, jump_off, jump_pc, alu_finish);
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
case (alu_op)
|
if(alu_start)
|
||||||
`ALU_OP_JMP_REL3,
|
case (alu_op)
|
||||||
`ALU_OP_JMP_REL4,
|
`ALU_OP_JMP_REL2,
|
||||||
`ALU_OP_JMP_ABS5:
|
`ALU_OP_JMP_REL3,
|
||||||
if (alu_start)
|
`ALU_OP_JMP_REL4,
|
||||||
jump_off <= { 16'b0, p_src1 };
|
`ALU_OP_JMP_ABS5: jump_off <= { 16'b0, p_src1 };
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
// main case
|
// main case
|
||||||
case (alu_op)
|
case (alu_op)
|
||||||
|
@ -641,16 +628,18 @@ always @(posedge i_clk) begin
|
||||||
`ALU_OP_COPY,
|
`ALU_OP_COPY,
|
||||||
`ALU_OP_RST_BIT,
|
`ALU_OP_RST_BIT,
|
||||||
`ALU_OP_SET_BIT: c_res1 <= p_src1;
|
`ALU_OP_SET_BIT: c_res1 <= p_src1;
|
||||||
`ALU_OP_2CMPL:
|
`ALU_OP_2CMPL: begin
|
||||||
begin
|
|
||||||
c_carry <= (~p_src1 == 4'hf) && p_carry ;
|
c_carry <= (~p_src1 == 4'hf) && p_carry ;
|
||||||
c_res1 <= ~p_src1 + {3'b000, p_carry};
|
c_res1 <= ~p_src1 + {3'b000, p_carry};
|
||||||
is_zero <= ((~p_src1 + {3'b000, p_carry}) == 0) && alu_start?1:is_zero;
|
is_zero <= ((~p_src1 + {3'b000, p_carry}) == 0) && alu_start?1:is_zero;
|
||||||
end
|
end
|
||||||
|
`ALU_OP_DEC:
|
||||||
|
{c_carry, c_res1} <= p_src1 + 4'b1111 + {4'b0000, p_carry};
|
||||||
`ALU_OP_ADD:
|
`ALU_OP_ADD:
|
||||||
{c_carry, c_res1} <= p_src1 + p_src2 + {4'b0000, p_carry};
|
{c_carry, c_res1} <= p_src1 + p_src2 + {4'b0000, p_carry};
|
||||||
`ALU_OP_TEST_NEQ:
|
`ALU_OP_TEST_NEQ:
|
||||||
c_carry <= !(p_src1 == p_src2) || p_carry;
|
c_carry <= !(p_src1 == p_src2) || p_carry;
|
||||||
|
`ALU_OP_JMP_REL2: begin end // there is no middle part
|
||||||
`ALU_OP_JMP_REL3,
|
`ALU_OP_JMP_REL3,
|
||||||
`ALU_OP_JMP_REL4,
|
`ALU_OP_JMP_REL4,
|
||||||
`ALU_OP_JMP_ABS5: jump_off[f_cur*4+:4] <= p_src1;
|
`ALU_OP_JMP_ABS5: jump_off[f_cur*4+:4] <= p_src1;
|
||||||
|
@ -658,12 +647,12 @@ always @(posedge i_clk) begin
|
||||||
default: $display("#### CALC 2 UNHANDLED OPERATION %0d", alu_op);
|
default: $display("#### CALC 2 UNHANDLED OPERATION %0d", alu_op);
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
case (alu_op)
|
if (alu_finish)
|
||||||
`ALU_OP_JMP_REL3: if (alu_finish)
|
case (alu_op)
|
||||||
jump_off <= { {8{p_src1[3]}}, p_src1, jump_off[7:0] };
|
`ALU_OP_JMP_REL2: jump_off <= { {12{p_src1[3]}}, p_src1, jump_off[3:0] };
|
||||||
`ALU_OP_JMP_REL4: if (alu_finish)
|
`ALU_OP_JMP_REL3: jump_off <= { {8{p_src1[3]}}, p_src1, jump_off[7:0] };
|
||||||
jump_off <= { {4{p_src1[3]}}, p_src1, jump_off[11:0] };
|
`ALU_OP_JMP_REL4: jump_off <= { {4{p_src1[3]}}, p_src1, jump_off[11:0] };
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
// $display("-------C- SRC1 %b %h | ~SRC1 %b %h | PC %b | RES1 %b %h | CC %b",
|
// $display("-------C- SRC1 %b %h | ~SRC1 %b %h | PC %b | RES1 %b %h | CC %b",
|
||||||
// p_src1, p_src1, ~p_src1, ~p_src1, p_carry,
|
// p_src1, p_src1, ~p_src1, ~p_src1, p_carry,
|
||||||
|
@ -672,13 +661,62 @@ always @(posedge i_clk) begin
|
||||||
end
|
end
|
||||||
|
|
||||||
if (do_go_init) begin
|
if (do_go_init) begin
|
||||||
// $display("GO_INIT 3: imm %h", i_imm_value);
|
$display("GO_INIT 3: imm %h", i_imm_value);
|
||||||
jump_off <= { {16{1'b0}}, i_imm_value};
|
jump_off <= { {16{1'b0}}, i_imm_value};
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* save alu registers after calculations
|
||||||
|
*
|
||||||
|
* this is the only place the registers can be updated !
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
reg [0:0] alu_initializing;
|
||||||
|
|
||||||
always @(posedge i_clk) begin
|
always @(posedge i_clk) begin
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialization of all registers
|
||||||
|
* This happens at the same time the first LOAD_PC command goes out
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (i_reset) begin
|
||||||
|
alu_initializing <= 1;
|
||||||
|
CARRY <= 0;
|
||||||
|
P <= 0;
|
||||||
|
D0 <= 0;
|
||||||
|
D1 <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (alu_initializing) begin
|
||||||
|
A[f_cur] <= 0;
|
||||||
|
B[f_cur] <= 0;
|
||||||
|
C[f_cur] <= 0;
|
||||||
|
D[f_cur] <= 0;
|
||||||
|
R0[f_cur] <= 0;
|
||||||
|
R1[f_cur] <= 0;
|
||||||
|
R2[f_cur] <= 0;
|
||||||
|
R3[f_cur] <= 0;
|
||||||
|
R4[f_cur] <= 0;
|
||||||
|
ST[f_cur] <= 0;
|
||||||
|
HST[f_cur[1:0]] <= 0;
|
||||||
|
alu_initializing <= (f_cur != 15);
|
||||||
|
end
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Debug for some JUMP condition testing
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
if (do_alu_save || do_go_prep) begin
|
if (do_alu_save || do_go_prep) begin
|
||||||
if (alu_debug_jump) begin
|
if (alu_debug_jump) begin
|
||||||
`ifdef SIM
|
`ifdef SIM
|
||||||
|
@ -714,10 +752,6 @@ always @(posedge i_clk) begin
|
||||||
alu_run, alu_done, o_alu_stall_dec, alu_op,
|
alu_run, alu_done, o_alu_stall_dec, alu_op,
|
||||||
f_first, f_cur, f_last, reg_dest, c_res1, c_res2, p_src1, p_src2, c_carry);
|
f_first, f_cur, f_last, reg_dest, c_res1, c_res2, p_src1, p_src2, c_carry);
|
||||||
|
|
||||||
// $display("-------S- SRC1 %b %h | ~SRC1 %b %h | PC %b | RES1 %b %h | CC %b",
|
|
||||||
// p_src1, p_src1, ~p_src1, ~p_src1, p_carry,
|
|
||||||
// (~p_src1) + p_carry, (~p_src1) + p_carry,
|
|
||||||
// (~p_src1) == 4'hf );
|
|
||||||
end
|
end
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
|
@ -726,6 +760,7 @@ always @(posedge i_clk) begin
|
||||||
`ALU_OP_COPY,
|
`ALU_OP_COPY,
|
||||||
`ALU_OP_EXCH, // does the first assign
|
`ALU_OP_EXCH, // does the first assign
|
||||||
`ALU_OP_2CMPL,
|
`ALU_OP_2CMPL,
|
||||||
|
`ALU_OP_DEC,
|
||||||
`ALU_OP_ADD,
|
`ALU_OP_ADD,
|
||||||
`ALU_OP_CLR_MASK:
|
`ALU_OP_CLR_MASK:
|
||||||
case (reg_dest)
|
case (reg_dest)
|
||||||
|
@ -756,6 +791,7 @@ always @(posedge i_clk) begin
|
||||||
endcase
|
endcase
|
||||||
`ALU_OP_TEST_EQ,
|
`ALU_OP_TEST_EQ,
|
||||||
`ALU_OP_TEST_NEQ,
|
`ALU_OP_TEST_NEQ,
|
||||||
|
`ALU_OP_JMP_REL2,
|
||||||
`ALU_OP_JMP_REL3,
|
`ALU_OP_JMP_REL3,
|
||||||
`ALU_OP_JMP_REL4,
|
`ALU_OP_JMP_REL4,
|
||||||
`ALU_OP_JMP_ABS5: begin end // nothing to save, handled by PC management below
|
`ALU_OP_JMP_ABS5: begin end // nothing to save, handled by PC management below
|
||||||
|
@ -772,13 +808,13 @@ always @(posedge i_clk) begin
|
||||||
`ALU_REG_B: B[f_cur] <= c_res2;
|
`ALU_REG_B: B[f_cur] <= c_res2;
|
||||||
`ALU_REG_C: C[f_cur] <= c_res2;
|
`ALU_REG_C: C[f_cur] <= c_res2;
|
||||||
`ALU_REG_D: D[f_cur] <= c_res2;
|
`ALU_REG_D: D[f_cur] <= c_res2;
|
||||||
|
`ALU_REG_D0: D0[f_cur*4+:4] <= c_res2;
|
||||||
|
`ALU_REG_D1: D1[f_cur*4+:4] <= c_res2;
|
||||||
`ALU_REG_R0: R0[f_cur] <= c_res2;
|
`ALU_REG_R0: R0[f_cur] <= c_res2;
|
||||||
`ALU_REG_R1: R1[f_cur] <= c_res2;
|
`ALU_REG_R1: R1[f_cur] <= c_res2;
|
||||||
`ALU_REG_R2: R2[f_cur] <= c_res2;
|
`ALU_REG_R2: R2[f_cur] <= c_res2;
|
||||||
`ALU_REG_R3: R3[f_cur] <= c_res2;
|
`ALU_REG_R3: R3[f_cur] <= c_res2;
|
||||||
`ALU_REG_R4: R4[f_cur] <= c_res2;
|
`ALU_REG_R4: R4[f_cur] <= c_res2;
|
||||||
// `ALU_REG_D0: D0[f_start*4+:4] <= c_res2;
|
|
||||||
// `ALU_REG_D1: D1[f_start*4+:4] <= c_res2;
|
|
||||||
// `ALU_REG_ST: ST[f_start*4+:4] <= c_res2;
|
// `ALU_REG_ST: ST[f_start*4+:4] <= c_res2;
|
||||||
// `ALU_REG_P: P <= c_res2;
|
// `ALU_REG_P: P <= c_res2;
|
||||||
// `ALU_REG_HST: HST <= c_res2;
|
// `ALU_REG_HST: HST <= c_res2;
|
||||||
|
@ -792,6 +828,8 @@ always @(posedge i_clk) begin
|
||||||
if (do_alu_save) begin
|
if (do_alu_save) begin
|
||||||
case (alu_op)
|
case (alu_op)
|
||||||
`ALU_OP_2CMPL: CARRY <= !is_zero;
|
`ALU_OP_2CMPL: CARRY <= !is_zero;
|
||||||
|
`ALU_OP_DEC,
|
||||||
|
`ALU_OP_ADD,
|
||||||
`ALU_OP_TEST_EQ,
|
`ALU_OP_TEST_EQ,
|
||||||
`ALU_OP_TEST_NEQ: CARRY <= c_carry;
|
`ALU_OP_TEST_NEQ: CARRY <= c_carry;
|
||||||
endcase
|
endcase
|
||||||
|
@ -964,32 +1002,69 @@ end
|
||||||
wire [19:0] next_pc;
|
wire [19:0] next_pc;
|
||||||
wire [19:0] goyes_off;
|
wire [19:0] goyes_off;
|
||||||
wire [19:0] goyes_pc;
|
wire [19:0] goyes_pc;
|
||||||
|
|
||||||
|
wire [0:0] is_jmp_rel2;
|
||||||
|
wire [0:0] is_rtn_rel2;
|
||||||
|
wire [0:0] jmp_carry_test;
|
||||||
|
wire [0:0] exec_rtn_rel2;
|
||||||
|
wire [0:0] set_jmp_rel2;
|
||||||
|
wire [0:0] exec_jmp_rel2;
|
||||||
|
|
||||||
wire [0:0] update_pc;
|
wire [0:0] update_pc;
|
||||||
wire [0:0] uncond_jmp;
|
wire [0:0] set_unc_jmp;
|
||||||
|
wire [0:0] exec_unc_jmp;
|
||||||
|
wire [0:0] exec_unc_rtn;
|
||||||
wire [0:0] pop_pc;
|
wire [0:0] pop_pc;
|
||||||
wire [0:0] reload_pc;
|
wire [0:0] reload_pc;
|
||||||
wire [0:0] push_pc;
|
wire [0:0] push_pc;
|
||||||
|
|
||||||
|
|
||||||
assign next_pc = (is_alu_op_jump && alu_finish)?jump_pc:PC + 1;
|
|
||||||
assign goyes_off = {{12{i_imm_value[3]}}, i_imm_value, jump_off[3:0]};
|
assign goyes_off = {{12{i_imm_value[3]}}, i_imm_value, jump_off[3:0]};
|
||||||
assign goyes_pc = jump_bse + goyes_off;
|
assign goyes_pc = jump_bse + goyes_off;
|
||||||
|
// rtnyes is already handled by i_ins_test_go
|
||||||
|
assign is_rtn_rel2 = (alu_op == `ALU_OP_JMP_REL2) && (goyes_off == 0);
|
||||||
|
assign is_jmp_rel2 = (alu_op == `ALU_OP_JMP_REL2) && !(goyes_off == 0);
|
||||||
|
assign jmp_carry_test = (i_test_carry && (CARRY == i_carry_val));
|
||||||
|
assign exec_rtn_rel2 = is_rtn_rel2 && jmp_carry_test && alu_done;
|
||||||
|
assign set_jmp_rel2 = is_jmp_rel2 && jmp_carry_test && alu_finish;
|
||||||
|
assign exec_jmp_rel2 = is_jmp_rel2 && jmp_carry_test && alu_done;
|
||||||
|
|
||||||
assign update_pc = !o_alu_stall_dec || is_alu_op_jump || just_reset;
|
|
||||||
assign uncond_jmp = is_alu_op_jump && alu_done;
|
assign set_unc_jmp = is_alu_op_unc_jump && alu_finish;
|
||||||
assign pop_pc = i_pop && i_ins_rtn &&
|
assign exec_unc_jmp = is_alu_op_unc_jump && alu_done;
|
||||||
((!i_ins_test_go) ||
|
assign exec_unc_rtn = i_pop && i_ins_rtn;
|
||||||
(i_ins_test_go && c_carry));
|
|
||||||
assign reload_pc = uncond_jmp || pop_pc || just_reset;
|
assign pop_pc = i_pop && i_ins_rtn &&
|
||||||
|
((!i_ins_test_go) ||
|
||||||
|
(i_ins_test_go && CARRY));
|
||||||
|
|
||||||
|
assign next_pc = (set_unc_jmp || set_jmp_rel2)?jump_pc:PC + 1;
|
||||||
|
assign update_pc = !o_alu_stall_dec || exec_unc_jmp || exec_jmp_rel2 || just_reset;
|
||||||
|
assign reload_pc = (exec_unc_jmp || pop_pc || just_reset || exec_jmp_rel2);
|
||||||
assign push_pc = update_pc && i_push && alu_finish;
|
assign push_pc = update_pc && i_push && alu_finish;
|
||||||
|
|
||||||
always @(posedge i_clk) begin
|
always @(posedge i_clk) begin
|
||||||
|
|
||||||
|
/*
|
||||||
|
* initializes the PC
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
if (i_reset) begin
|
if (i_reset) begin
|
||||||
PC <= ~0;
|
PC <= ~0;
|
||||||
o_bus_load_pc <= 0;
|
o_bus_load_pc <= 0;
|
||||||
|
rstk_ptr <= 0;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Similarly to the data registers,
|
||||||
|
* initializes the RSTK while the PC is first loaded
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
if (alu_initializing)
|
||||||
|
RSTK[f_cur[2:0]] <= 0;
|
||||||
|
|
||||||
|
|
||||||
// necessary for the write to memory above
|
// necessary for the write to memory above
|
||||||
// otherwise we get a conflict on o_bus_address
|
// otherwise we get a conflict on o_bus_address
|
||||||
if (setup_load_dp)
|
if (setup_load_dp)
|
||||||
|
@ -1016,16 +1091,18 @@ always @(posedge i_clk) begin
|
||||||
`ifdef SIM
|
`ifdef SIM
|
||||||
if (alu_debug_pc)
|
if (alu_debug_pc)
|
||||||
$display({"ALU_PC 3: !stl %b | nx %5h | done %b | fin %b | ",
|
$display({"ALU_PC 3: !stl %b | nx %5h | done %b | fin %b | ",
|
||||||
"jmp %b | ins_rtn %b | push %b | ",
|
"uncjmp %b | ins_rtn %b | push %b | imm %h | ",
|
||||||
"imm %h | j_bs %h | go_off %h | go_pc %h"},
|
"c_test %b | jmpr2 %b | rtn[n]c %b |",
|
||||||
|
"j_bs %h | go_off %h | go_pc %h | update %b | PC <= %h"},
|
||||||
!o_alu_stall_dec, next_pc, alu_done, alu_finish,
|
!o_alu_stall_dec, next_pc, alu_done, alu_finish,
|
||||||
is_alu_op_jump, i_ins_rtn, i_push,
|
is_alu_op_unc_jump, i_ins_rtn, i_push, i_imm_value,
|
||||||
i_imm_value, jump_bse, goyes_off, goyes_pc);
|
jmp_carry_test, exec_jmp_rel2, exec_rtn_rel2,
|
||||||
|
jump_bse, goyes_off, goyes_pc, update_pc, pop_pc ? RSTK[rstk_ptr - 1] : next_pc);
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
// this may do wierd things with C=RSTK...
|
// this may do wierd things with C=RSTK...
|
||||||
if (update_pc) begin
|
if (update_pc) begin
|
||||||
PC <= pop_pc ? RSTK[rstk_ptr-1] : next_pc;
|
PC <= pop_pc ? RSTK[rstk_ptr - 1] : next_pc;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (reload_pc) begin
|
if (reload_pc) begin
|
||||||
|
@ -1066,12 +1143,16 @@ end
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
always @(posedge i_clk)
|
always @(posedge i_clk) begin
|
||||||
|
if (i_reset)
|
||||||
|
DEC <= 0;
|
||||||
|
|
||||||
// changing calculation modes
|
// changing calculation modes
|
||||||
if (do_alu_mode) begin
|
if (do_alu_mode) begin
|
||||||
$display("SETTING MODE TO %s", i_mode_dec?"DEC":"HEX");
|
$display("SETTING MODE TO %s", i_mode_dec?"DEC":"HEX");
|
||||||
DEC <= i_mode_dec;
|
DEC <= i_mode_dec;
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
@ -86,6 +86,16 @@ assign en_bus_ecmd = i_en_bus_ecmd && !i_stalled;
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
// tests on last_cmd
|
||||||
|
|
||||||
|
wire [0:0] last_cmd_pc_read;
|
||||||
|
wire [0:0] last_cmd_dp_read;
|
||||||
|
wire [0:0] last_cmd_dp_write;
|
||||||
|
|
||||||
|
assign last_cmd_pc_read = (last_cmd == `BUSCMD_PC_READ);
|
||||||
|
assign last_cmd_dp_read = (last_cmd == `BUSCMD_DP_READ);
|
||||||
|
assign last_cmd_dp_write = (last_cmd == `BUSCMD_DP_WRITE);
|
||||||
|
|
||||||
// declarations
|
// declarations
|
||||||
|
|
||||||
reg [0:0] cmd_pc_read_s;
|
reg [0:0] cmd_pc_read_s;
|
||||||
|
@ -98,7 +108,7 @@ reg [0:0] cmd_reset_s;
|
||||||
wire [0:0] addr_s;
|
wire [0:0] addr_s;
|
||||||
|
|
||||||
wire [0:0] do_cmd_pc_read;
|
wire [0:0] do_cmd_pc_read;
|
||||||
wire [0:0] do_display_stalled;
|
wire [0:0] do_display_stalled;
|
||||||
|
|
||||||
wire [0:0] do_cmd_load_dp;
|
wire [0:0] do_cmd_load_dp;
|
||||||
wire [0:0] do_dp_read_data;
|
wire [0:0] do_dp_read_data;
|
||||||
|
@ -108,6 +118,7 @@ wire [0:0] do_pc_read_after_dp_read;
|
||||||
wire [0:0] do_cleanup_after_dp_read;
|
wire [0:0] do_cleanup_after_dp_read;
|
||||||
|
|
||||||
wire [0:0] do_cmd_dp_write;
|
wire [0:0] do_cmd_dp_write;
|
||||||
|
wire [0:0] cmd_dp_write_data;
|
||||||
wire [0:0] do_dp_write_data;
|
wire [0:0] do_dp_write_data;
|
||||||
wire [0:0] do_pc_read_after_dp_write;
|
wire [0:0] do_pc_read_after_dp_write;
|
||||||
wire [0:0] cmd_load_dp_dp_write_uc;
|
wire [0:0] cmd_load_dp_dp_write_uc;
|
||||||
|
@ -122,8 +133,10 @@ wire [0:0] do_pc_read_after_reset;
|
||||||
wire [0:0] cmd_reset_sc;
|
wire [0:0] cmd_reset_sc;
|
||||||
wire [0:0] cmd_reset_uc;
|
wire [0:0] cmd_reset_uc;
|
||||||
|
|
||||||
wire [0:0] do_unstall;
|
|
||||||
wire [0:0] do_cleanup;
|
wire [0:0] do_cleanup;
|
||||||
|
wire [0:0] do_stall;
|
||||||
|
wire [0:0] do_unstall;
|
||||||
|
wire [0:0] do_stop_loop;
|
||||||
|
|
||||||
// assigns
|
// assigns
|
||||||
|
|
||||||
|
@ -138,7 +151,8 @@ assign do_pc_read_after_dp_read = i_read_stall && !i_cmd_dp_read && cmd_load_dp
|
||||||
assign do_cleanup_after_dp_read = !i_read_stall && !i_cmd_dp_read && cmd_load_dp_s && !addr_s && dp_read_s;
|
assign do_cleanup_after_dp_read = !i_read_stall && !i_cmd_dp_read && cmd_load_dp_s && !addr_s && dp_read_s;
|
||||||
|
|
||||||
assign do_cmd_dp_write = i_cmd_dp_write && cmd_load_dp_s && addr_s && !cmd_dp_write_s;
|
assign do_cmd_dp_write = i_cmd_dp_write && cmd_load_dp_s && addr_s && !cmd_dp_write_s;
|
||||||
assign do_dp_write_data = i_cmd_dp_write && cmd_load_dp_s && addr_s && cmd_dp_write_s;
|
assign cmd_dp_write_data = i_cmd_dp_write && cmd_load_dp_s && addr_s && cmd_dp_write_s;
|
||||||
|
assign do_dp_write_data = en_bus_send && cmd_dp_write_data && last_cmd_dp_write;
|
||||||
assign do_pc_read_after_dp_write = !i_cmd_dp_write && cmd_load_dp_s && cmd_dp_write_s;
|
assign do_pc_read_after_dp_write = !i_cmd_dp_write && cmd_load_dp_s && cmd_dp_write_s;
|
||||||
assign cmd_load_dp_dp_write_uc = cmd_load_dp_s && cmd_dp_write_s && cmd_pc_read_s;
|
assign cmd_load_dp_dp_write_uc = cmd_load_dp_s && cmd_dp_write_s && cmd_pc_read_s;
|
||||||
|
|
||||||
|
@ -163,18 +177,28 @@ assign do_display_stalled = en_bus_recv && i_read_stall && !o_stalled_by_
|
||||||
do_dp_read_data ||
|
do_dp_read_data ||
|
||||||
do_pc_read_after_dp_read ||
|
do_pc_read_after_dp_read ||
|
||||||
do_cmd_dp_write ||
|
do_cmd_dp_write ||
|
||||||
do_dp_write_data ||
|
cmd_dp_write_data ||
|
||||||
do_pc_read_after_dp_write);
|
do_pc_read_after_dp_write);
|
||||||
|
|
||||||
assign do_unstall = do_dp_read_data_uc ||
|
assign do_cleanup = en_bus_send &&
|
||||||
cmd_load_dp_dp_write_uc ||
|
(do_cleanup_after_dp_read ||
|
||||||
cmd_config_uc ||
|
cmd_load_dp_dp_write_uc ||
|
||||||
cmd_reset_uc;
|
cmd_config_uc ||
|
||||||
|
cmd_reset_uc);
|
||||||
|
|
||||||
|
assign do_stall = en_bus_ecmd &&
|
||||||
|
(do_dp_read_data_sc ||
|
||||||
|
cmd_reset_sc ||
|
||||||
|
cmd_config_sc);
|
||||||
|
|
||||||
|
assign do_unstall = en_bus_ecmd &&
|
||||||
|
(do_dp_read_data_uc ||
|
||||||
|
cmd_load_dp_dp_write_uc ||
|
||||||
|
cmd_config_uc ||
|
||||||
|
cmd_reset_uc);
|
||||||
|
|
||||||
|
assign do_stop_loop = en_bus_ecmd && addr_s;
|
||||||
|
|
||||||
assign do_cleanup = do_cleanup_after_dp_read ||
|
|
||||||
cmd_load_dp_dp_write_uc ||
|
|
||||||
cmd_config_uc ||
|
|
||||||
cmd_reset_uc;
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
* test rom
|
* test rom
|
||||||
|
@ -184,22 +208,24 @@ assign do_cleanup = do_cleanup_after_dp_read ||
|
||||||
`ifdef SIM
|
`ifdef SIM
|
||||||
`define ROMBITS 20
|
`define ROMBITS 20
|
||||||
`else
|
`else
|
||||||
`define ROMBITS 16
|
`define ROMBITS 12
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
reg [3:0] rom [0:2**`ROMBITS-1];
|
reg [3:0] rom [0:2**`ROMBITS-1];
|
||||||
|
|
||||||
wire [0:0] last_cmd_pc_read;
|
|
||||||
wire [0:0] last_cmd_dp_read;
|
|
||||||
wire [0:0] do_read_from_bus;
|
wire [0:0] do_read_from_bus;
|
||||||
wire [0:0] use_pc_as_pointer;
|
wire [0:0] use_pc_as_pointer;
|
||||||
|
wire [0:0] use_dp_as_pointer;
|
||||||
|
wire [0:0] do_read_from_bus_with_pc;
|
||||||
|
wire [0:0] do_read_from_bus_with_dp;
|
||||||
wire [`ROMBITS-1:0] read_pointer;
|
wire [`ROMBITS-1:0] read_pointer;
|
||||||
|
|
||||||
assign last_cmd_pc_read = (last_cmd == `BUSCMD_PC_READ);
|
assign do_read_from_bus = en_bus_recv && (!i_read_stall || do_dp_read_data) && (last_cmd_pc_read || last_cmd_dp_read);
|
||||||
assign last_cmd_dp_read = (last_cmd == `BUSCMD_DP_READ);
|
assign use_pc_as_pointer = last_cmd_pc_read;
|
||||||
assign do_read_from_bus = en_bus_recv && (!i_read_stall || do_dp_read_data) && (last_cmd_pc_read || last_cmd_dp_read);
|
assign use_dp_as_pointer = last_cmd_dp_read;
|
||||||
assign use_pc_as_pointer = last_cmd_pc_read ;
|
assign read_pointer = use_pc_as_pointer?local_pc[`ROMBITS-1:0]:local_dp[`ROMBITS-1:0];
|
||||||
assign read_pointer = use_pc_as_pointer?local_pc[`ROMBITS-1:0]:local_dp[`ROMBITS-1:0];
|
assign do_read_from_bus_with_pc = do_read_from_bus && use_pc_as_pointer;
|
||||||
|
assign do_read_from_bus_with_dp = do_read_from_bus && use_dp_as_pointer;
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
|
@ -210,7 +236,7 @@ assign read_pointer = use_pc_as_pointer?local_pc[`ROMBITS-1:0]:local_dp[`RO
|
||||||
initial begin
|
initial begin
|
||||||
// `ifdef SIM
|
// `ifdef SIM
|
||||||
$readmemh("rom-gx-r.hex", rom, 0, 2**`ROMBITS-1);
|
$readmemh("rom-gx-r.hex", rom, 0, 2**`ROMBITS-1);
|
||||||
// $readmemh( "testrom-2.hex", rom);
|
// $readmemh( "testrom-2.hex", rom);
|
||||||
|
|
||||||
`ifdef SIM
|
`ifdef SIM
|
||||||
// $monitor({"o_stalled_by_bus %b | i_read_stall %b | i_cmd_dp_read %b |",
|
// $monitor({"o_stalled_by_bus %b | i_read_stall %b | i_cmd_dp_read %b |",
|
||||||
|
@ -243,6 +269,19 @@ always @(posedge i_clk) begin
|
||||||
cmd_reset_s <= 0;
|
cmd_reset_s <= 0;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
/*
|
||||||
|
* reset flags
|
||||||
|
*/
|
||||||
|
if (do_cleanup) begin
|
||||||
|
// $display("--------------------------------------------- BUS STATES CLEANUP");
|
||||||
|
cmd_pc_read_s <= 0;
|
||||||
|
dp_read_s <= 0;
|
||||||
|
cmd_dp_write_s <= 0;
|
||||||
|
cmd_load_dp_s <= 0;
|
||||||
|
cmd_config_s <= 0;
|
||||||
|
cmd_reset_s <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* sending commands or data to the bus
|
* sending commands or data to the bus
|
||||||
|
@ -250,20 +289,6 @@ always @(posedge i_clk) begin
|
||||||
*/
|
*/
|
||||||
if (en_bus_send) begin
|
if (en_bus_send) begin
|
||||||
|
|
||||||
/*
|
|
||||||
* reset flags
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (do_cleanup) begin
|
|
||||||
// $display("--------------------------------------------- BUS STATES CLEANUP");
|
|
||||||
cmd_pc_read_s <= 0;
|
|
||||||
dp_read_s <= 0;
|
|
||||||
cmd_dp_write_s <= 0;
|
|
||||||
cmd_load_dp_s <= 0;
|
|
||||||
cmd_config_s <= 0;
|
|
||||||
cmd_reset_s <= 0;
|
|
||||||
end
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* send the PC_READ command to restore the instruction flow
|
* send the PC_READ command to restore the instruction flow
|
||||||
* after a data transfer
|
* after a data transfer
|
||||||
|
@ -342,46 +367,54 @@ always @(posedge i_clk) begin
|
||||||
addr_cnt <= addr_cnt + 1;
|
addr_cnt <= addr_cnt + 1;
|
||||||
o_bus_strobe <= 1;
|
o_bus_strobe <= 1;
|
||||||
end
|
end
|
||||||
|
|
||||||
/*
|
|
||||||
* nothing to do for reading data
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* writing data to the bus,
|
|
||||||
* send DP_WRITE first if necessary
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (do_dp_write_data) begin
|
|
||||||
if (last_cmd == `BUSCMD_DP_WRITE) begin
|
|
||||||
$display("BUS_SEND %0d: [%d] WRITE %h =>", `PH_BUS_SEND, i_cycle_ctr, i_nibble);
|
|
||||||
o_bus_data <= i_nibble;
|
|
||||||
o_bus_strobe <= 1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
/*
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* writing data to the bus,
|
||||||
|
* will wait for DP_WRITE to be sent
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
if (do_dp_write_data) begin
|
||||||
|
$display("BUS_SEND %0d: [%d] WRITE %h =>", `PH_BUS_SEND, i_cycle_ctr, i_nibble);
|
||||||
|
o_bus_data <= i_nibble;
|
||||||
|
o_bus_strobe <= 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
*
|
*
|
||||||
* reading data from the bus
|
* reading data from the bus
|
||||||
*
|
*
|
||||||
*/
|
***************************************************************************/
|
||||||
|
|
||||||
if (do_read_from_bus) begin
|
/*
|
||||||
|
* only display during simulation
|
||||||
|
*/
|
||||||
`ifdef SIM
|
`ifdef SIM
|
||||||
|
|
||||||
|
if (do_read_from_bus)
|
||||||
$display("BUS_RECV %0d: [%d] <= READ(%s) [%5h] %h",
|
$display("BUS_RECV %0d: [%d] <= READ(%s) [%5h] %h",
|
||||||
`PH_BUS_RECV, i_cycle_ctr, use_pc_as_pointer?"PC":"DP",
|
`PH_BUS_RECV, i_cycle_ctr, use_pc_as_pointer?"PC":"DP",
|
||||||
read_pointer, rom[read_pointer]);
|
read_pointer, rom[read_pointer]);
|
||||||
|
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
|
if (do_read_from_bus)
|
||||||
o_nibble <= rom[read_pointer];
|
o_nibble <= rom[read_pointer];
|
||||||
if (use_pc_as_pointer) local_pc <= local_pc + 1;
|
|
||||||
else begin
|
|
||||||
local_dp <= local_dp + 1;
|
if (do_read_from_bus_with_pc)
|
||||||
dp_read_s <= 1;
|
local_pc <= local_pc + 1;
|
||||||
end
|
|
||||||
end
|
if (do_read_from_bus_with_dp) begin
|
||||||
|
local_dp <= local_dp + 1;
|
||||||
|
dp_read_s <= 1;
|
||||||
|
end
|
||||||
|
|
||||||
if (do_display_stalled) begin
|
if (do_display_stalled) begin
|
||||||
$display("BUS_RECV %0d: [%d] STALLED", `PH_BUS_RECV, i_cycle_ctr);
|
$display("BUS_RECV %0d: [%d] STALLED", `PH_BUS_RECV, i_cycle_ctr);
|
||||||
|
@ -397,28 +430,35 @@ always @(posedge i_clk) begin
|
||||||
o_bus_cmd_data <= 1;
|
o_bus_cmd_data <= 1;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* execute stalling the core by the bus controller
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
if (do_stall) begin
|
||||||
|
// $display("-------------------------------------- STALL");
|
||||||
|
o_stalled_by_bus <= 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (do_unstall) begin
|
||||||
|
// $display("-------------------------------------- NO - STALL");
|
||||||
|
o_stalled_by_bus <= 0;
|
||||||
|
addr_cnt <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
/*
|
||||||
|
* reset the adress sending loop
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (do_stop_loop) begin
|
||||||
|
send_addr <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
if (en_bus_ecmd) begin
|
if (en_bus_ecmd) begin
|
||||||
|
|
||||||
// stalling and unstalling stuff
|
|
||||||
|
|
||||||
if (do_dp_read_data_sc || cmd_reset_sc || cmd_config_sc) begin
|
|
||||||
// $display("-------------------------------------- STALL");
|
|
||||||
o_stalled_by_bus <= 1;
|
|
||||||
end
|
|
||||||
|
|
||||||
if (do_unstall) begin
|
|
||||||
// $display("-------------------------------------- NO - STALL");
|
|
||||||
o_stalled_by_bus <= 0;
|
|
||||||
addr_cnt <= 0;
|
|
||||||
end
|
|
||||||
|
|
||||||
if (addr_s) begin
|
|
||||||
send_addr <= 0;
|
|
||||||
end
|
|
||||||
|
|
||||||
// command automatic switchover
|
// command automatic switchover
|
||||||
|
|
||||||
case (last_cmd)
|
case (last_cmd)
|
||||||
`BUSCMD_NOP: begin end
|
`BUSCMD_NOP: begin end
|
||||||
`BUSCMD_LOAD_PC,
|
`BUSCMD_LOAD_PC,
|
||||||
|
@ -446,9 +486,6 @@ always @(posedge i_clk) begin
|
||||||
`BUSCMD_RESET: begin end
|
`BUSCMD_RESET: begin end
|
||||||
default: $display("------------ UNHANDLED BUSCMD %h", last_cmd);
|
default: $display("------------ UNHANDLED BUSCMD %h", last_cmd);
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
131
saturn_core.v
131
saturn_core.v
|
@ -22,23 +22,51 @@
|
||||||
|
|
||||||
`ifdef SIM
|
`ifdef SIM
|
||||||
module saturn_core (
|
module saturn_core (
|
||||||
input clk,
|
i_clk,
|
||||||
input reset,
|
i_reset,
|
||||||
output [0:0] halt,
|
o_halt,
|
||||||
output [3:0] busstate,
|
|
||||||
output [11:0] decstate
|
i_bus_data_in,
|
||||||
|
o_bus_data_out,
|
||||||
|
o_bus_strobe,
|
||||||
|
o_bus_cmd_data
|
||||||
);
|
);
|
||||||
|
|
||||||
|
input wire [0:0] i_clk;
|
||||||
|
input wire [0:0] i_reset;
|
||||||
|
output wire [0:0] o_halt;
|
||||||
|
|
||||||
|
input wire [3:0] i_bus_data_in;
|
||||||
|
output wire [3:0] o_bus_data_out;
|
||||||
|
output wire [0:0] o_bus_strobe;
|
||||||
|
output wire [0:0] o_bus_cmd_data;
|
||||||
|
|
||||||
`else
|
`else
|
||||||
module saturn_core (
|
module saturn_core (
|
||||||
input clk_25mhz,
|
clk_25mhz,
|
||||||
input [6:0] btn,
|
btn,
|
||||||
output [7:0] led
|
led,
|
||||||
);
|
|
||||||
wire clk;
|
|
||||||
wire reset;
|
|
||||||
|
|
||||||
assign clk = clk_25mhz;
|
i_bus_data_in,
|
||||||
assign reset = btn[1];
|
o_bus_data_out,
|
||||||
|
o_bus_strobe,
|
||||||
|
o_bus_cmd_data
|
||||||
|
);
|
||||||
|
|
||||||
|
input wire [0:0] clk_25mhz;
|
||||||
|
input wire [6:0] btn;
|
||||||
|
output reg [7:0] led;
|
||||||
|
|
||||||
|
wire [0:0] i_clk;
|
||||||
|
wire [0:0] i_reset;
|
||||||
|
|
||||||
|
assign i_clk = clk_25mhz;
|
||||||
|
assign i_reset = btn[1];
|
||||||
|
|
||||||
|
input wire [3:0] i_bus_data_in;
|
||||||
|
output wire [3:0] o_bus_data_out;
|
||||||
|
output wire [0:0] o_bus_strobe;
|
||||||
|
output wire [0:0] o_bus_cmd_data;
|
||||||
|
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
|
@ -65,10 +93,6 @@ reg [0:0] clock_end;
|
||||||
reg [31:0] cycle_ctr;
|
reg [31:0] cycle_ctr;
|
||||||
reg [31:0] max_cycle;
|
reg [31:0] max_cycle;
|
||||||
|
|
||||||
// state machine stuff
|
|
||||||
wire [0:0] halt;
|
|
||||||
|
|
||||||
|
|
||||||
// hp48_bus bus_ctrl (
|
// hp48_bus bus_ctrl (
|
||||||
// .strobe (bus_strobe),
|
// .strobe (bus_strobe),
|
||||||
// .reset (reset),
|
// .reset (reset),
|
||||||
|
@ -80,8 +104,8 @@ wire [0:0] halt;
|
||||||
// );
|
// );
|
||||||
|
|
||||||
saturn_decoder m_decoder (
|
saturn_decoder m_decoder (
|
||||||
.i_clk (clk),
|
.i_clk (i_clk),
|
||||||
.i_reset (reset),
|
.i_reset (i_reset),
|
||||||
.i_cycles (cycle_ctr),
|
.i_cycles (cycle_ctr),
|
||||||
.i_en_dbg (ck_debugger),
|
.i_en_dbg (ck_debugger),
|
||||||
.i_en_dec (ck_inst_dec),
|
.i_en_dec (ck_inst_dec),
|
||||||
|
@ -116,6 +140,7 @@ saturn_decoder m_decoder (
|
||||||
.o_ins_rtn (ins_rtn),
|
.o_ins_rtn (ins_rtn),
|
||||||
.o_set_xm (set_xm),
|
.o_set_xm (set_xm),
|
||||||
.o_set_carry (set_carry),
|
.o_set_carry (set_carry),
|
||||||
|
.o_test_carry (test_carry),
|
||||||
.o_carry_val (carry_val),
|
.o_carry_val (carry_val),
|
||||||
.o_ins_set_mode (ins_set_mode),
|
.o_ins_set_mode (ins_set_mode),
|
||||||
.o_mode_dec (mode_dec),
|
.o_mode_dec (mode_dec),
|
||||||
|
@ -149,6 +174,7 @@ wire [4:0] reg_src2;
|
||||||
wire [0:0] ins_rtn;
|
wire [0:0] ins_rtn;
|
||||||
wire [0:0] set_xm;
|
wire [0:0] set_xm;
|
||||||
wire [0:0] set_carry;
|
wire [0:0] set_carry;
|
||||||
|
wire [0:0] test_carry;
|
||||||
wire [0:0] carry_val;
|
wire [0:0] carry_val;
|
||||||
wire [0:0] ins_set_mode;
|
wire [0:0] ins_set_mode;
|
||||||
wire [0:0] mode_dec;
|
wire [0:0] mode_dec;
|
||||||
|
@ -160,8 +186,8 @@ wire [0:0] ins_unconfig;
|
||||||
|
|
||||||
|
|
||||||
saturn_alu m_alu (
|
saturn_alu m_alu (
|
||||||
.i_clk (clk),
|
.i_clk (i_clk),
|
||||||
.i_reset (reset),
|
.i_reset (i_reset),
|
||||||
.i_cycle_ctr (cycle_ctr),
|
.i_cycle_ctr (cycle_ctr),
|
||||||
.i_en_alu_dump (ck_alu_dump),
|
.i_en_alu_dump (ck_alu_dump),
|
||||||
.i_en_alu_prep (ck_alu_prep),
|
.i_en_alu_prep (ck_alu_prep),
|
||||||
|
@ -207,6 +233,7 @@ saturn_alu m_alu (
|
||||||
.i_mode_dec (mode_dec),
|
.i_mode_dec (mode_dec),
|
||||||
.i_set_xm (set_xm),
|
.i_set_xm (set_xm),
|
||||||
.i_set_carry (set_carry),
|
.i_set_carry (set_carry),
|
||||||
|
.i_test_carry (test_carry),
|
||||||
.i_carry_val (carry_val),
|
.i_carry_val (carry_val),
|
||||||
|
|
||||||
.o_reg_p (reg_p),
|
.o_reg_p (reg_p),
|
||||||
|
@ -238,8 +265,8 @@ wire [19:0] reg_pc;
|
||||||
|
|
||||||
saturn_bus_ctrl m_bus_ctrl (
|
saturn_bus_ctrl m_bus_ctrl (
|
||||||
// basic stuff
|
// basic stuff
|
||||||
.i_clk (clk),
|
.i_clk (i_clk),
|
||||||
.i_reset (reset),
|
.i_reset (i_reset),
|
||||||
.i_cycle_ctr (cycle_ctr),
|
.i_cycle_ctr (cycle_ctr),
|
||||||
.i_en_bus_send (ck_bus_send),
|
.i_en_bus_send (ck_bus_send),
|
||||||
.i_en_bus_recv (ck_bus_recv),
|
.i_en_bus_recv (ck_bus_recv),
|
||||||
|
@ -249,10 +276,10 @@ saturn_bus_ctrl m_bus_ctrl (
|
||||||
.o_stalled_by_bus (bus_stalls_core),
|
.o_stalled_by_bus (bus_stalls_core),
|
||||||
|
|
||||||
//bus i/o
|
//bus i/o
|
||||||
.i_bus_data (bus_data_in),
|
.i_bus_data (i_bus_data_in),
|
||||||
.o_bus_data (bus_data_out),
|
.o_bus_data (o_bus_data_out),
|
||||||
.o_bus_strobe (bus_strobe),
|
.o_bus_strobe (o_bus_strobe),
|
||||||
.o_bus_cmd_data (bus_cmd_data),
|
.o_bus_cmd_data (o_bus_cmd_data),
|
||||||
|
|
||||||
// interface to the rest of the machine
|
// interface to the rest of the machine
|
||||||
.i_alu_pc (reg_pc),
|
.i_alu_pc (reg_pc),
|
||||||
|
@ -271,11 +298,11 @@ saturn_bus_ctrl m_bus_ctrl (
|
||||||
reg [0:0] mem_ctrl_stall;
|
reg [0:0] mem_ctrl_stall;
|
||||||
wire [0:0] bus_stalls_core;
|
wire [0:0] bus_stalls_core;
|
||||||
|
|
||||||
// bus to external modules
|
// // bus to external modules
|
||||||
reg [3:0] bus_data_in;
|
// reg [3:0] bus_data_in;
|
||||||
wire [3:0] bus_data_out;
|
// wire [3:0] bus_data_out;
|
||||||
wire [0:0] bus_strobe;
|
// wire [0:0] bus_strobe;
|
||||||
wire [0:0] bus_cmd_data;
|
// wire [0:0] bus_cmd_data;
|
||||||
|
|
||||||
// `define DEBUG_CLOCKS
|
// `define DEBUG_CLOCKS
|
||||||
|
|
||||||
|
@ -318,8 +345,8 @@ initial begin
|
||||||
//
|
//
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge i_clk) begin
|
||||||
if (!reset) begin
|
if (!i_reset) begin
|
||||||
clk_phase <= clk_phase + 1;
|
clk_phase <= clk_phase + 1;
|
||||||
ck_debugger <= clk_phase[1:0] == `PH_DEBUGGER;
|
ck_debugger <= clk_phase[1:0] == `PH_DEBUGGER;
|
||||||
|
|
||||||
|
@ -363,7 +390,7 @@ always @(posedge clk) begin
|
||||||
|
|
||||||
clock_end <= 0;
|
clock_end <= 0;
|
||||||
cycle_ctr <= ~0;
|
cycle_ctr <= ~0;
|
||||||
max_cycle <= 450;
|
max_cycle <= 650;
|
||||||
|
|
||||||
mem_ctrl_stall <= 0;
|
mem_ctrl_stall <= 0;
|
||||||
`ifndef SIM
|
`ifndef SIM
|
||||||
|
@ -382,8 +409,9 @@ wire dec_stalled;
|
||||||
wire alu_stalled;
|
wire alu_stalled;
|
||||||
assign dec_stalled = alu_stalls_dec || bus_stalls_core;
|
assign dec_stalled = alu_stalls_dec || bus_stalls_core;
|
||||||
assign alu_stalled = bus_stalls_core;
|
assign alu_stalled = bus_stalls_core;
|
||||||
assign halt = clock_end || inv_opcode;
|
`ifdef SIM
|
||||||
|
assign o_halt = clock_end || inv_opcode;
|
||||||
|
`endif
|
||||||
|
|
||||||
// Verilator lint_off UNUSED
|
// Verilator lint_off UNUSED
|
||||||
//wire [N-1:0] unused;
|
//wire [N-1:0] unused;
|
||||||
|
@ -394,25 +422,32 @@ endmodule
|
||||||
`ifdef SIM
|
`ifdef SIM
|
||||||
|
|
||||||
module saturn_tb;
|
module saturn_tb;
|
||||||
reg clk;
|
|
||||||
reg reset;
|
|
||||||
wire halt;
|
|
||||||
wire [3:0] busstate;
|
|
||||||
wire [11:0] decstate;
|
|
||||||
|
|
||||||
saturn_core saturn (
|
saturn_core saturn (
|
||||||
.clk (clk),
|
.i_clk (clk),
|
||||||
.reset (reset),
|
.i_reset (reset),
|
||||||
.halt (halt),
|
.o_halt (halt),
|
||||||
.busstate (busstate),
|
.i_bus_data_in (core_bus_data_in),
|
||||||
.decstate (decstate)
|
.o_bus_data_out (core_bus_data_out),
|
||||||
|
.o_bus_strobe (core_bus_strobe),
|
||||||
|
.o_bus_cmd_data (core_bus_cmd_data)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
reg [0:0] clk;
|
||||||
|
reg [0:0] reset;
|
||||||
|
wire [0:0] halt;
|
||||||
|
|
||||||
|
reg [3:0] core_bus_data_in;
|
||||||
|
wire [3:0] core_bus_data_out;
|
||||||
|
wire [0:0] core_bus_strobe;
|
||||||
|
wire [0:0] core_bus_cmd_data;
|
||||||
|
|
||||||
always
|
always
|
||||||
#10 clk = (clk === 1'b0);
|
#10 clk = (clk === 1'b0);
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
//$monitor ("c %b | r %b | run %h | dec %h", clk, reset, runstate, decstate);
|
// $monitor ("c %b | r %b | in %h | out %h | str %b | cd %b",
|
||||||
|
// clk, reset, core_bus_data_in, core_bus_data_out, core_bus_strobe, core_bus_cmd_data);
|
||||||
end
|
end
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
|
|
|
@ -191,6 +191,7 @@ always @(posedge i_clk) begin
|
||||||
o_ins_set_mode <= 0;
|
o_ins_set_mode <= 0;
|
||||||
o_ins_reset <= 0;
|
o_ins_reset <= 0;
|
||||||
o_ins_config <= 0;
|
o_ins_config <= 0;
|
||||||
|
o_test_carry <= 0;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (decoder_active) begin
|
if (decoder_active) begin
|
||||||
|
@ -290,6 +291,7 @@ always @(posedge i_clk) begin
|
||||||
// 4xy GOC
|
// 4xy GOC
|
||||||
// 500 RTNNC
|
// 500 RTNNC
|
||||||
// 5xy GONC
|
// 5xy GONC
|
||||||
|
o_alu_debug <= 1;
|
||||||
o_alu_no_stall <= 1;
|
o_alu_no_stall <= 1;
|
||||||
o_alu_op <= `ALU_OP_JMP_REL2;
|
o_alu_op <= `ALU_OP_JMP_REL2;
|
||||||
mem_load_max <= 1;
|
mem_load_max <= 1;
|
||||||
|
@ -319,6 +321,13 @@ always @(posedge i_clk) begin
|
||||||
o_fields_table <= `FT_TABLE_a;
|
o_fields_table <= `FT_TABLE_a;
|
||||||
block_Ax <= 1;
|
block_Ax <= 1;
|
||||||
end
|
end
|
||||||
|
4'hB: begin
|
||||||
|
go_fields_table <= 1;
|
||||||
|
// we don't know, safe bet is table a, but could be table b,
|
||||||
|
// works either way, table is fixed on the next nibble
|
||||||
|
o_fields_table <= `FT_TABLE_a;
|
||||||
|
block_Bx <= 1;
|
||||||
|
end
|
||||||
4'hC: block_Cx <= 1;
|
4'hC: block_Cx <= 1;
|
||||||
4'hD: block_Dx <= 1;
|
4'hD: block_Dx <= 1;
|
||||||
4'hF: block_Fx <= 1;
|
4'hF: block_Fx <= 1;
|
||||||
|
@ -572,6 +581,15 @@ always @(posedge i_clk) begin
|
||||||
|
|
||||||
`include "saturn_decoder_block_8.v"
|
`include "saturn_decoder_block_8.v"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Block Axx
|
||||||
|
* ra=ra+rb a
|
||||||
|
* ra=ra-1 a
|
||||||
|
* ra=0 b
|
||||||
|
* ra=rb b
|
||||||
|
* rarbEX b
|
||||||
|
*/
|
||||||
|
|
||||||
if (do_block_Ax) begin
|
if (do_block_Ax) begin
|
||||||
o_fields_table <= i_nibble[3]?`FT_TABLE_b:`FT_TABLE_a;
|
o_fields_table <= i_nibble[3]?`FT_TABLE_b:`FT_TABLE_a;
|
||||||
block_Aax <= !i_nibble[3];
|
block_Aax <= !i_nibble[3];
|
||||||
|
@ -597,10 +615,67 @@ always @(posedge i_clk) begin
|
||||||
block_Abx <= 0;
|
block_Abx <= 0;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Block Bxx
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
if (do_block_Bx) begin
|
||||||
|
o_fields_table <= i_nibble[3]?`FT_TABLE_b:`FT_TABLE_a;
|
||||||
|
block_Bax <= !i_nibble[3];
|
||||||
|
block_Bbx <= i_nibble[3];
|
||||||
|
block_Bx <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (do_block_Bax) begin
|
||||||
|
`ifdef SIM
|
||||||
|
$display("block_Bax %h", i_nibble);
|
||||||
|
`endif
|
||||||
|
o_ins_alu_op <= 1;
|
||||||
|
case ({i_nibble[3],i_nibble[2]})
|
||||||
|
2'b00: o_alu_op <= `ALU_OP_SUB;
|
||||||
|
2'b01: o_alu_op <= `ALU_OP_INC;
|
||||||
|
2'b10: o_alu_op <= `ALU_OP_SUB;
|
||||||
|
2'b11: o_alu_op <= `ALU_OP_SUB;
|
||||||
|
endcase
|
||||||
|
next_nibble <= 0;
|
||||||
|
o_ins_decoded <= 1;
|
||||||
|
`ifdef SIM
|
||||||
|
o_unimplemented <= 0;
|
||||||
|
`endif
|
||||||
|
block_Bax <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (do_block_Bbx) begin
|
||||||
|
o_ins_alu_op <= 1;
|
||||||
|
case ({i_nibble[3],i_nibble[2]})
|
||||||
|
2'b00: o_alu_op <= `ALU_OP_SHL;
|
||||||
|
2'b01: o_alu_op <= `ALU_OP_SHR;
|
||||||
|
2'b10: o_alu_op <= `ALU_OP_2CMPL;
|
||||||
|
2'b11: o_alu_op <= `ALU_OP_1CMPL;
|
||||||
|
endcase
|
||||||
|
next_nibble <= 0;
|
||||||
|
o_ins_decoded <= 1;
|
||||||
|
`ifdef SIM
|
||||||
|
o_unimplemented <= 0;
|
||||||
|
`endif
|
||||||
|
block_Bbx <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Block Cx
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
if (do_block_Cx) begin
|
if (do_block_Cx) begin
|
||||||
`ifdef SIM
|
`ifdef SIM
|
||||||
$display("block_Cx %h", i_nibble);
|
$display("block_Cx %h", i_nibble);
|
||||||
`endif
|
`endif
|
||||||
|
// o_alu_debug <= 1;
|
||||||
o_fields_table <= `FT_TABLE_f;
|
o_fields_table <= `FT_TABLE_f;
|
||||||
o_ins_alu_op <= 1;
|
o_ins_alu_op <= 1;
|
||||||
o_alu_op <= (i_nibble[3] && i_nibble[2])?`ALU_OP_DEC:`ALU_OP_ADD;
|
o_alu_op <= (i_nibble[3] && i_nibble[2])?`ALU_OP_DEC:`ALU_OP_ADD;
|
||||||
|
@ -628,6 +703,10 @@ always @(posedge i_clk) begin
|
||||||
end
|
end
|
||||||
|
|
||||||
if (do_block_Fx) begin
|
if (do_block_Fx) begin
|
||||||
|
`ifdef SIM
|
||||||
|
|
||||||
|
`endif
|
||||||
|
|
||||||
case (i_nibble)
|
case (i_nibble)
|
||||||
4'h8, 4'h9, 4'hA, 4'hB: // r=-r A
|
4'h8, 4'h9, 4'hA, 4'hB: // r=-r A
|
||||||
begin
|
begin
|
||||||
|
|
|
@ -109,6 +109,18 @@ reg block_Abx;
|
||||||
wire do_block_Abx;
|
wire do_block_Abx;
|
||||||
assign do_block_Abx = do_on_other_nibbles && block_Abx;
|
assign do_block_Abx = do_on_other_nibbles && block_Abx;
|
||||||
|
|
||||||
|
reg block_Bx;
|
||||||
|
wire do_block_Bx;
|
||||||
|
assign do_block_Bx = do_on_other_nibbles && block_Bx;
|
||||||
|
|
||||||
|
reg block_Bax;
|
||||||
|
wire do_block_Bax;
|
||||||
|
assign do_block_Bax = do_on_other_nibbles && block_Bax;
|
||||||
|
|
||||||
|
reg block_Bbx;
|
||||||
|
wire do_block_Bbx;
|
||||||
|
assign do_block_Bbx = do_on_other_nibbles && block_Bbx;
|
||||||
|
|
||||||
reg block_Cx;
|
reg block_Cx;
|
||||||
wire do_block_Cx;
|
wire do_block_Cx;
|
||||||
assign do_block_Cx = do_on_other_nibbles && block_Cx;
|
assign do_block_Cx = do_on_other_nibbles && block_Cx;
|
||||||
|
|
|
@ -222,6 +222,8 @@ always @(posedge i_clk) begin
|
||||||
`ALU_REG_B: $write("B");
|
`ALU_REG_B: $write("B");
|
||||||
`ALU_REG_C: $write("C");
|
`ALU_REG_C: $write("C");
|
||||||
`ALU_REG_D: $write("D");
|
`ALU_REG_D: $write("D");
|
||||||
|
`ALU_REG_D0: $write("D0");
|
||||||
|
`ALU_REG_D1: $write("D1");
|
||||||
`ALU_REG_RSTK: $write("RSTK");
|
`ALU_REG_RSTK: $write("RSTK");
|
||||||
`ALU_REG_IMM: $write("\t%0d", o_imm_value+1);
|
`ALU_REG_IMM: $write("\t%0d", o_imm_value+1);
|
||||||
default: $write("[src2:%0d]", o_reg_src2);
|
default: $write("[src2:%0d]", o_reg_src2);
|
||||||
|
|
|
@ -63,6 +63,11 @@ always @(posedge i_clk) begin
|
||||||
o_field <= 0;
|
o_field <= 0;
|
||||||
o_field_valid <= 0;
|
o_field_valid <= 0;
|
||||||
case (i_nibble)
|
case (i_nibble)
|
||||||
|
4'h4, 4'h5: begin // RTNC / GOC / RTNNC / GONC
|
||||||
|
$display("------------------------------------------------ 4/5xx JUMP setting fields");
|
||||||
|
o_field_start <= 0;
|
||||||
|
o_field_last <= 1;
|
||||||
|
end
|
||||||
4'h6, 4'h7: begin // GOTO / GOSUB
|
4'h6, 4'h7: begin // GOTO / GOSUB
|
||||||
o_field_start <= 0;
|
o_field_start <= 0;
|
||||||
o_field_last <= 2;
|
o_field_last <= 2;
|
||||||
|
|
|
@ -35,7 +35,7 @@ always @(posedge i_clk) begin
|
||||||
if (do_on_first_nibble) begin
|
if (do_on_first_nibble) begin
|
||||||
// reset values on instruction decode start
|
// reset values on instruction decode start
|
||||||
case (i_nibble)
|
case (i_nibble)
|
||||||
4'h6, 4'h7: begin
|
4'h4, 4'h5, 4'h6, 4'h7: begin
|
||||||
o_reg_dest <= 0;
|
o_reg_dest <= 0;
|
||||||
o_reg_src1 <= `ALU_REG_IMM;
|
o_reg_src1 <= `ALU_REG_IMM;
|
||||||
o_reg_src2 <= 0;
|
o_reg_src2 <= 0;
|
||||||
|
@ -125,7 +125,8 @@ always @(posedge i_clk) begin
|
||||||
|
|
||||||
if (do_block_13x) begin
|
if (do_block_13x) begin
|
||||||
o_reg_dest <= i_nibble[1]?reg_A_C:reg_D0D1;
|
o_reg_dest <= i_nibble[1]?reg_A_C:reg_D0D1;
|
||||||
o_reg_src1 <= i_nibble[1]?reg_D0D1:reg_A_C;
|
o_reg_src1 <= i_nibble[2]?`ALU_REG_C:`ALU_REG_A;
|
||||||
|
o_reg_src2 <= i_nibble[1]?reg_D0D1:0;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (do_block_14x_15xx) begin
|
if (do_block_14x_15xx) begin
|
||||||
|
@ -190,29 +191,60 @@ always @(posedge i_clk) begin
|
||||||
|
|
||||||
if (do_block_Abx || do_block_Dx) begin
|
if (do_block_Abx || do_block_Dx) begin
|
||||||
case ({i_nibble[3],i_nibble[2]})
|
case ({i_nibble[3],i_nibble[2]})
|
||||||
2'b00: begin
|
2'b00: begin
|
||||||
o_reg_dest <= reg_ABCD;
|
o_reg_dest <= reg_ABCD;
|
||||||
o_reg_src1 <= `ALU_REG_ZERO;
|
o_reg_src1 <= `ALU_REG_ZERO;
|
||||||
o_reg_src2 <= 0;
|
o_reg_src2 <= 0;
|
||||||
end
|
end
|
||||||
2'b01: begin
|
2'b01: begin
|
||||||
o_reg_dest <= reg_ABCD;
|
o_reg_dest <= reg_ABCD;
|
||||||
o_reg_src1 <= reg_BCAC;
|
o_reg_src1 <= reg_BCAC;
|
||||||
o_reg_src2 <= 0;
|
o_reg_src2 <= 0;
|
||||||
end
|
end
|
||||||
2'b10: begin
|
2'b10: begin
|
||||||
o_reg_dest <= reg_BCAC;
|
o_reg_dest <= reg_BCAC;
|
||||||
o_reg_src1 <= reg_ABCD;
|
o_reg_src1 <= reg_ABCD;
|
||||||
o_reg_src2 <= 0;
|
o_reg_src2 <= 0;
|
||||||
end
|
end
|
||||||
2'b11: begin // exch
|
2'b11: begin // exch
|
||||||
o_reg_dest <= reg_ABAC;
|
o_reg_dest <= reg_ABAC;
|
||||||
o_reg_src1 <= reg_ABAC;
|
o_reg_src1 <= reg_ABAC;
|
||||||
o_reg_src2 <= reg_BCCD;
|
o_reg_src2 <= reg_BCCD;
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if (do_block_Bax) begin
|
||||||
|
case ({i_nibble[3],i_nibble[2]})
|
||||||
|
2'b00: begin
|
||||||
|
o_reg_dest <= reg_ABCD;
|
||||||
|
o_reg_src1 <= reg_ABCD;
|
||||||
|
o_reg_src2 <= reg_BCAC;
|
||||||
|
end
|
||||||
|
2'b01: begin
|
||||||
|
o_reg_dest <= reg_ABCD;
|
||||||
|
o_reg_src1 <= reg_ABCD;
|
||||||
|
o_reg_src2 <= 0;
|
||||||
|
end
|
||||||
|
2'b10: begin
|
||||||
|
o_reg_dest <= reg_BCAC;
|
||||||
|
o_reg_src1 <= reg_BCAC;
|
||||||
|
o_reg_src2 <= reg_ABCD;
|
||||||
|
end
|
||||||
|
2'b11: begin
|
||||||
|
o_reg_dest <= reg_ABCD;
|
||||||
|
o_reg_src1 <= reg_BCAC;
|
||||||
|
o_reg_src2 <= reg_ABCD;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
if (do_block_Bbx) begin
|
||||||
|
o_reg_dest <= reg_ABCD;
|
||||||
|
o_reg_src1 <= reg_ABCD;
|
||||||
|
o_reg_src2 <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
if (do_block_Cx) begin
|
if (do_block_Cx) begin
|
||||||
case ({i_nibble[3],i_nibble[2]})
|
case ({i_nibble[3],i_nibble[2]})
|
||||||
2'b00: begin
|
2'b00: begin
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
3 4 1 0 0 0 0
|
2 3
|
||||||
F A // NOP3
|
4 D F
|
||||||
|
3 1 4 3
|
Loading…
Reference in a new issue