implement the pieces to replicate the bus data transfers for writing data out.

This commit is contained in:
Raphael Jacquot 2019-02-17 12:05:38 +01:00
parent 128921c364
commit 8fc7cde507
5 changed files with 244 additions and 80 deletions

View file

@ -16,6 +16,7 @@
module saturn_alu ( module saturn_alu (
i_clk, i_clk,
i_reset, i_reset,
i_cycle_ctr,
i_en_alu_dump, i_en_alu_dump,
i_en_alu_prep, i_en_alu_prep,
i_en_alu_calc, i_en_alu_calc,
@ -26,6 +27,8 @@ module saturn_alu (
o_bus_address, o_bus_address,
o_bus_load_pc, o_bus_load_pc,
o_bus_load_dp, o_bus_load_dp,
o_bus_read_pc,
o_bus_write_dp,
o_bus_nibble_out, o_bus_nibble_out,
i_push, i_push,
@ -61,6 +64,7 @@ module saturn_alu (
input wire [0:0] i_clk; input wire [0:0] i_clk;
input wire [0:0] i_reset; input wire [0:0] i_reset;
input wire [31:0] i_cycle_ctr;
input wire [0:0] i_en_alu_dump; input wire [0:0] i_en_alu_dump;
input wire [0:0] i_en_alu_prep; input wire [0:0] i_en_alu_prep;
input wire [0:0] i_en_alu_calc; input wire [0:0] i_en_alu_calc;
@ -71,6 +75,8 @@ input wire [0:0] i_stalled;
output reg [19:0] o_bus_address; output reg [19:0] o_bus_address;
output reg [0:0] o_bus_load_pc; output reg [0:0] o_bus_load_pc;
output reg [0:0] o_bus_load_dp; output reg [0:0] o_bus_load_dp;
output reg [0:0] o_bus_read_pc;
output reg [0:0] o_bus_write_dp;
output reg [3:0] o_bus_nibble_out; output reg [3:0] o_bus_nibble_out;
input wire [0:0] i_push; input wire [0:0] i_push;
@ -261,7 +267,7 @@ wire do_alu_pc;
wire do_alu_mode; wire do_alu_mode;
assign do_busclean = alu_active && i_en_alu_dump; assign do_busclean = alu_active && i_en_alu_dump;
assign do_alu_init = alu_active && i_en_alu_init && i_ins_alu_op && !alu_run; assign do_alu_init = alu_active && i_en_alu_init && i_ins_alu_op && !alu_run && !write_done;
assign do_alu_prep = alu_active && i_en_alu_prep && alu_run; assign do_alu_prep = alu_active && i_en_alu_prep && alu_run;
assign do_alu_calc = alu_active && i_en_alu_calc && alu_run; assign do_alu_calc = alu_active && i_en_alu_calc && alu_run;
assign do_alu_save = alu_active && i_en_alu_save && alu_run; assign do_alu_save = alu_active && i_en_alu_save && alu_run;
@ -277,7 +283,9 @@ assign do_go_prep = alu_active && i_en_alu_prep && i_ins_test_go;
// 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 = alu_run && (!i_alu_no_stall || alu_finish || alu_go_test); assign o_alu_stall_dec = (!no_extra_cycles) ||
(alu_run &&
(!i_alu_no_stall || alu_finish || alu_go_test));
wire alu_start; wire alu_start;
wire alu_finish; wire alu_finish;
@ -309,9 +317,9 @@ assign is_alu_op_test = ((alu_op == `ALU_OP_TEST_EQ) ||
always @(posedge i_clk) begin always @(posedge i_clk) begin
`ifdef SIM `ifdef SIM
if (i_stalled && i_en_alu_dump) // if (i_stalled && i_en_alu_dump)
$display("ALU STALLED"); // $display("ALU STALLED");
`endif // `endif
`ifdef ALU_DEBUG_DBG `ifdef ALU_DEBUG_DBG
$display("iad %b | AD %b | ad %b | ADD %b | add %b | ADJ %b | adj %b | ADP %b | adp %b", $display("iad %b | AD %b | ad %b | ADD %b | add %b | ADJ %b | adj %b | ADP %b | adp %b",
@ -376,18 +384,6 @@ always @(posedge i_clk) begin
reg_src2 <= i_reg_src2; reg_src2 <= i_reg_src2;
f_last <= i_field_last; f_last <= i_field_last;
if (is_mem_xfer) begin
`ifdef SIM
$display("ALU_XFER 3: read %b | write %b | mem_reg DAT%b",
is_mem_read, is_mem_write, mem_reg[0]);
$display(".------------------------------------.");
$display("| SHOULD TELL THE BUS CONTROLLER TO |");
$display("| LOAD D0 OR D1 INTO MODULES' DP REG |");
$display("`------------------------------------´");
`endif
// DO SOMETHING TO GET THE BUS CONTROLLER TO SEND OUT
// THE CONTENTS OF D0 OR D1 AS THE DP
end
end end
end end
@ -398,6 +394,7 @@ end
always @(posedge i_clk) begin always @(posedge i_clk) begin
if (do_alu_init) begin if (do_alu_init) begin
$display("------------------------------------------------- DO_ALU_INIT");
alu_run <= 1; alu_run <= 1;
f_first <= i_field_start; f_first <= i_field_start;
f_cur <= i_field_start; f_cur <= i_field_start;
@ -552,7 +549,7 @@ always @(posedge i_clk) begin
if (do_alu_calc) begin if (do_alu_calc) begin
`ifdef SIM `ifdef SIM
if (alu_debug) if (alu_debug)
$display("ALU_CALC 2: run %b | done %b | stall %b | op %d | f %h | c %h | l %h | dest %d | src1 %h | src2 %h | p_carry %b", $display("ALU_CALC 2: run %b | done %b | stall %b | op %d | f %h | c %h | l %h | dest %d | psrc1 %h | psrc2 %h | p_carry %b",
alu_run, alu_done, o_alu_stall_dec, alu_op, f_first, f_cur, f_last, reg_dest, p_src1, p_src2, p_carry); alu_run, alu_done, o_alu_stall_dec, alu_op, f_first, f_cur, f_last, reg_dest, p_src1, p_src2, p_carry);
if (alu_debug_jump) if (alu_debug_jump)
$display("ALU_JUMP 2: run %b | done %b | stall %b | op %d | f %h | c %h | l %h | jbs %5h | jof %5h | jpc %5h | fin %b", $display("ALU_JUMP 2: run %b | done %b | stall %b | op %d | f %h | c %h | l %h | jbs %5h | jof %5h | jpc %5h | fin %b",
@ -650,15 +647,18 @@ always @(posedge i_clk) begin
`ALU_OP_ADD, `ALU_OP_ADD,
`ALU_OP_CLR_MASK: `ALU_OP_CLR_MASK:
case (reg_dest) case (reg_dest)
`ALU_REG_A: A[f_cur*4+:4] <= c_res1; `ALU_REG_A: A[f_cur*4+:4] <= c_res1;
`ALU_REG_B: B[f_cur*4+:4] <= c_res1; `ALU_REG_B: B[f_cur*4+:4] <= c_res1;
`ALU_REG_C: C[f_cur*4+:4] <= c_res1; `ALU_REG_C: C[f_cur*4+:4] <= c_res1;
`ALU_REG_D: D[f_cur*4+:4] <= c_res1; `ALU_REG_D: D[f_cur*4+:4] <= c_res1;
`ALU_REG_D0: D0[f_cur*4+:4] <= c_res1; `ALU_REG_D0: D0[f_cur*4+:4] <= c_res1;
`ALU_REG_D1: D1[f_cur*4+:4] <= c_res1; `ALU_REG_D1: D1[f_cur*4+:4] <= c_res1;
`ALU_REG_ST: ST[f_cur*4+:4] <= c_res1; `ALU_REG_ST: ST[f_cur*4+:4] <= c_res1;
`ALU_REG_P: P <= c_res1; `ALU_REG_P: P <= c_res1;
`ALU_REG_HST: HST <= c_res1; `ALU_REG_DAT0,
`ALU_REG_DAT1: o_bus_nibble_out <= c_res1;
`ALU_REG_HST: HST <= c_res1;
default: $display("#### ALU_SAVE invalid register %0d for op %0d", reg_dest, alu_op);
endcase endcase
`ALU_OP_RST_BIT, `ALU_OP_RST_BIT,
`ALU_OP_SET_BIT: `ALU_OP_SET_BIT:
@ -733,6 +733,11 @@ 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;
reg [1:0] extra_cycles;
wire [0:0] no_extra_cycles;
wire [1:0] cycles_to_go;
reg [0:0] write_done;
assign next_pc = (is_alu_op_jump && alu_finish)?jump_pc:PC + 1; 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;
@ -745,10 +750,17 @@ assign pop_pc = i_pop && i_ins_rtn &&
assign reload_pc = uncond_jmp || pop_pc || just_reset; assign reload_pc = uncond_jmp || pop_pc || just_reset;
assign push_pc = update_pc && i_push && alu_finish; assign push_pc = update_pc && i_push && alu_finish;
assign no_extra_cycles = (extra_cycles == 0);
assign cycles_to_go = extra_cycles - 1;
always @(posedge i_clk) begin always @(posedge i_clk) begin
if (i_reset) begin if (i_reset) begin
PC <= ~0; PC <= ~0;
just_reset <= 1; just_reset <= 1;
extra_cycles <= 0;
o_bus_load_pc <= 0;
o_bus_load_dp <= 0;
o_bus_write_dp <= 0;
end end
@ -766,8 +778,74 @@ always @(posedge i_clk) begin
`endif `endif
/* /*
* updates the PC *
* Request the D0 or D1 pointers to be loaded to other
* modules through the bus
*
*/ */
// $display("[!no_ec %b] || ( [run %b] && ( [!nstll %b] || [fin %b] || [test %b] ))",
// !no_extra_cycles, alu_run, !i_alu_no_stall, alu_finish, alu_go_test);
if (do_alu_init) begin
if (is_mem_xfer && !write_done) begin
`ifdef SIM
$display("ALU_XFER 3: read %b | write %b | mem_reg DAT%b",
is_mem_read, is_mem_write, mem_reg[0]);
// $display(".------------------------------------.");
// $display("| SHOULD TELL THE BUS CONTROLLER TO |");
// $display("| LOAD D0 OR D1 INTO MODULES' DP REG |");
// $display("`------------------------------------´");
`endif
// DO SOMETHING TO GET THE BUS CONTROLLER TO SEND OUT
// THE CONTENTS OF D0 OR D1 AS THE DP
case (mem_reg[0])
0: o_bus_address <= D0;
1: o_bus_address <= D1;
endcase
o_bus_load_dp <= 1;
end
end
if (do_busclean && alu_run && !write_done)
if (is_mem_write && !o_bus_write_dp) begin
// $display("ALUWRITE %0d: [%d] setting up write", `PH_ALU_DUMP, i_cycle_ctr);
o_bus_write_dp <= 1;
end
// writing needs one more cycle as the DP_WRITE command
// needs to be send
if (do_alu_save && alu_finish && is_mem_write && (extra_cycles == 0)) begin
// $display("ALUWRITE %0d: [%d] 2 EXTRA CYCLES", `PH_ALU_SAVE, i_cycle_ctr);
extra_cycles <= 2;
write_done <= 1;
end
if (i_en_alu_calc && !no_extra_cycles) begin
// $display("ALUWRITE %0d: [%d] %0d CYCLES TO GO", `PH_ALU_SAVE, i_cycle_ctr, cycles_to_go);
extra_cycles <= cycles_to_go;
if (cycles_to_go == 1) begin
o_bus_write_dp <= 0;
o_bus_read_pc <= 1;
end
end
if (i_en_alu_dump && no_extra_cycles && o_bus_read_pc) begin
// $display("ALUWRITE %0d: [%d] RELEASE DECODER", `PH_ALU_DUMP, i_cycle_ctr);
o_bus_read_pc <= 0;
write_done <= 0;
end
/**
*
* Update the PC.
* Request the new PC be loaded to the other modules through
* the bus if necessary
*
*/
if (do_alu_pc) begin if (do_alu_pc) begin
// $display("DO ALU PC"); // $display("DO ALU PC");
`ifdef SIM `ifdef SIM
@ -778,19 +856,20 @@ always @(posedge i_clk) begin
!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_jump, i_ins_rtn, i_push,
i_imm_value, jump_bse, goyes_off, goyes_pc); i_imm_value, jump_bse, goyes_off, goyes_pc);
if (reload_pc) begin // if (reload_pc) begin
$display(".---------------------------------."); // $display(".---------------------------------.");
$display("| SHOULD TELL THE BUS CONTROLLER |"); // $display("| SHOULD TELL THE BUS CONTROLLER |");
$display("| TO LOAD PC INTO MODULES' PC REG |"); // $display("| TO LOAD PC INTO MODULES' PC REG |");
$display("`---------------------------------´"); // $display("`---------------------------------´");
end // end
`endif `endif
// if we just came out of reset, simulate a long jump to 0 // if we just came out of reset, simulate a long jump to 0
if (just_reset) begin if (just_reset) begin
$display("ALU_RSET 3: simulating GOVLNG to PC"); // $display("ALU_RSET 3: simulating GOVLNG to PC");
// cancel this signal for good once reset is gone // cancel this signal for good once reset is gone
just_reset <= 0; just_reset <= 0;
o_bus_read_pc <= 1;
end end
// this may do wierd things with C=RSTK... // this may do wierd things with C=RSTK...
@ -799,7 +878,7 @@ always @(posedge i_clk) begin
end end
if (reload_pc) begin if (reload_pc) begin
$display("ALU_PC 3: $$$$ RELOADING PC $$$$"); // $display("ALU_PC 3: $$$$ RELOADING PC $$$$");
o_bus_address <= pop_pc ? RSTK[rstk_ptr-1] : next_pc; o_bus_address <= pop_pc ? RSTK[rstk_ptr-1] : next_pc;
o_bus_load_pc <= 1; o_bus_load_pc <= 1;
end end
@ -819,9 +898,17 @@ always @(posedge i_clk) begin
end end
end end
// deactivate o_load_pc /*
if (do_busclean && o_bus_load_pc) *
o_bus_load_pc <= 0; * Deactivate the load_pc or load_dp enables on the next clock
*
*/
if (do_busclean && (o_bus_load_pc || o_bus_load_dp)) begin
$display("BUSCLEAN %0d: cleaning the various bus control bits", `PH_ALU_DUMP);
o_bus_load_pc <= 0;
o_bus_load_dp <= 0;
end
end end

View file

@ -28,6 +28,8 @@ module saturn_bus_ctrl (
i_address, i_address,
i_load_pc, i_load_pc,
i_load_dp, i_load_dp,
i_read_pc,
i_write_dp,
i_nibble, i_nibble,
o_nibble o_nibble
); );
@ -52,6 +54,8 @@ input wire [19:0] i_alu_pc;
input wire [19:0] i_address; input wire [19:0] i_address;
input wire [0:0] i_load_pc; input wire [0:0] i_load_pc;
input wire [0:0] i_load_dp; input wire [0:0] i_load_dp;
input wire [0:0] i_read_pc;
input wire [0:0] i_write_dp;
input wire [3:0] i_nibble; input wire [3:0] i_nibble;
output reg [3:0] o_nibble; output reg [3:0] o_nibble;
@ -84,21 +88,23 @@ initial begin
// $readmemh( "testrom-2.hex", rom); // $readmemh( "testrom-2.hex", rom);
// $monitor("addr %5h | strb %b | c/d %b | cnt %0d | odata %h | idata %h", // $monitor("addr %5h | strb %b | c/d %b | cnt %0d | odata %h | idata %h",
// i_address, o_bus_strobe, o_bus_cmd_data, addr_cnt, o_bus_data, i_bus_data); // i_address, o_bus_strobe, o_bus_cmd_data, addr_cnt, o_bus_data, i_bus_data);
// $monitor("MONITOR : strb %b | o_bus_data %h | i_bus_data %h", o_bus_strobe, o_bus_data, i_bus_data);
`endif `endif
end end
reg [2:0] addr_cnt; reg [3:0] last_cmd;
reg [2:0] addr_cnt;
reg [0:0] send_addr; reg [0:0] send_addr;
reg [19:0] local_pc; reg [19:0] local_pc;
reg [19:0] local_dp;
always @(posedge i_clk) begin always @(posedge i_clk) begin
if (i_reset) begin if (i_reset) begin
o_stalled_by_bus <= 0; o_stalled_by_bus <= 0;
o_bus_strobe <= 0; o_bus_strobe <= 0;
o_bus_cmd_data <= 1; // 1 is the default level o_bus_cmd_data <= 1; // 1 is the default level
addr_cnt <= 0; addr_cnt <= 0;
end end
/* /*
@ -108,35 +114,90 @@ always @(posedge i_clk) begin
*/ */
if (en_bus_send) begin if (en_bus_send) begin
/*
* Sending LOAD_PC or LOAD_DP
*/
if (i_load_pc) begin if (i_load_pc) begin
$display("BUS_SEND %0d: loading pc %h", `PH_BUS_SEND, i_address); $display("BUS_SEND %0d: [%d] LOAD_PC %h", `PH_BUS_SEND, i_cycle_ctr, i_address);
o_bus_data <= `BUSCMD_LOAD_PC; o_bus_data <= `BUSCMD_LOAD_PC;
last_cmd <= `BUSCMD_LOAD_PC;
end end
if (i_load_dp) begin if (i_load_dp) begin
$display("BUS_SEND %0d: loading dp %h", `PH_BUS_SEND, i_address); $display("BUS_SEND %0d: [%d] LOAD_DP %h", `PH_BUS_SEND, i_cycle_ctr, i_address);
o_bus_data <= `BUSCMD_LOAD_DP; o_bus_data <= `BUSCMD_LOAD_DP;
last_cmd <= `BUSCMD_LOAD_DP;
end end
if (i_load_pc || i_load_dp) begin if (i_load_pc || i_load_dp) begin
o_stalled_by_bus <= 1; o_stalled_by_bus <= 1;
o_bus_cmd_data <= 0; o_bus_cmd_data <= 0;
addr_cnt <= 0; addr_cnt <= 0;
send_addr <= 1; send_addr <= 1;
o_bus_strobe <= 1;
end end
// sending address bits
if (send_addr) begin if (send_addr) begin
$display("BUS_SEND %0d: send addr nibble %0d [%h]", `PH_BUS_SEND, addr_cnt, i_address[addr_cnt*4+:4]); $display("BUS_SEND %0d: [%d] addr[%0d] %h =>",
`PH_BUS_SEND, i_cycle_ctr, addr_cnt, i_address[addr_cnt*4+:4]);
o_bus_data <= i_address[addr_cnt*4+:4]; o_bus_data <= i_address[addr_cnt*4+:4];
addr_cnt <= addr_cnt + 1; addr_cnt <= addr_cnt + 1;
o_bus_strobe <= 1;
end end
if (!i_read_stall || send_addr) /*
* send the PC_READ command to restore the instruction flow
* after a data transfer
*/
if (i_read_pc) begin
if (last_cmd != `BUSCMD_PC_READ) begin
$display("BUS_SEND %0d: [%d] PC_READ", `PH_BUS_SEND, i_cycle_ctr);
o_bus_data <= `BUSCMD_PC_READ;
last_cmd <= `BUSCMD_PC_READ;
end
o_bus_strobe <= 1;
end
if ((last_cmd == `BUSCMD_PC_READ) && !i_read_stall)
o_bus_strobe <= 1;
/*
* writing data to the bus,
* send DP_WRITE first if necessary
*/
if (i_write_dp && (addr_cnt == 5)) begin
if (last_cmd != `BUSCMD_DP_WRITE) begin
$display("BUS_SEND %0d: [%d] DP_WRITE", `PH_BUS_SEND, i_cycle_ctr);
o_bus_data <= `BUSCMD_DP_WRITE;
last_cmd <= `BUSCMD_DP_WRITE;
o_bus_strobe <= 1; o_bus_strobe <= 1;
end else 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
if (en_bus_ecmd && send_addr && (addr_cnt == 5)) begin if (en_bus_ecmd && send_addr && (addr_cnt == 5)) begin
$display("BUS_ECMD %0d: releasing stall after sending addr", `PH_BUS_ECMD); case (last_cmd)
`BUSCMD_LOAD_PC: begin
$display("BUS_ECMD %0d: [%d] <= PC_READ mode", `PH_BUS_ECMD, i_cycle_ctr);
last_cmd <= `BUSCMD_PC_READ;
local_pc <= i_address;
end
`BUSCMD_LOAD_DP: begin
$display("BUS_ECMD %0d: [%d] <= DP_READ mode", `PH_BUS_ECMD, i_cycle_ctr);
last_cmd <= `BUSCMD_DP_READ;
local_dp <= i_address;
end
endcase
send_addr <= 0; send_addr <= 0;
o_stalled_by_bus = 0; o_stalled_by_bus = 0;
end end
@ -146,9 +207,15 @@ always @(posedge i_clk) begin
* reading data from the bus * reading data from the bus
* *
*/ */
if (en_bus_recv && !i_read_stall) begin if (en_bus_recv && !i_read_stall) begin
$display("BUS_RECV %0d: [%d] nibble %h", `PH_BUS_RECV, i_cycle_ctr, rom[i_alu_pc[`ROMBITS-1:0]]); if (last_cmd == `BUSCMD_PC_READ) begin
o_nibble <= rom[i_alu_pc[`ROMBITS-1:0]]; $display("BUS_RECV %0d: [%d] <= READ %h", `PH_BUS_RECV, i_cycle_ctr, rom[local_pc[`ROMBITS-1:0]]);
o_nibble <= rom[local_pc[`ROMBITS-1:0]];
local_pc <= local_pc + 1;
end else
$display("BUS_RECV %0d: [%d] UNKNOWN COMMAND %h", `PH_BUS_RECV, i_cycle_ctr, last_cmd);
end end
/* /*

View file

@ -86,6 +86,7 @@ saturn_decoder m_decoder (
.i_en_dbg (ck_debugger), .i_en_dbg (ck_debugger),
.i_en_dec (ck_inst_dec), .i_en_dec (ck_inst_dec),
.i_pc (reg_pc), .i_pc (reg_pc),
.i_bus_load_pc (bus_load_pc),
.i_stalled (dec_stalled), .i_stalled (dec_stalled),
.i_nibble (bus_nibble_in), .i_nibble (bus_nibble_in),
@ -156,6 +157,7 @@ wire [0:0] ins_test_go;
saturn_alu m_alu ( saturn_alu m_alu (
.i_clk (clk), .i_clk (clk),
.i_reset (reset), .i_reset (reset),
.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),
.i_en_alu_calc (ck_alu_calc), .i_en_alu_calc (ck_alu_calc),
@ -166,6 +168,8 @@ saturn_alu m_alu (
.o_bus_address (bus_address), .o_bus_address (bus_address),
.o_bus_load_pc (bus_load_pc), .o_bus_load_pc (bus_load_pc),
.o_bus_load_dp (bus_load_dp), .o_bus_load_dp (bus_load_dp),
.o_bus_read_pc (bus_read_pc),
.o_bus_write_dp (bus_write_dp),
.o_bus_nibble_out (bus_nibble_out), .o_bus_nibble_out (bus_nibble_out),
.i_push (push), .i_push (push),
@ -204,6 +208,8 @@ saturn_alu m_alu (
wire [19:0] bus_address; wire [19:0] bus_address;
wire [0:0] bus_load_pc; wire [0:0] bus_load_pc;
wire [0:0] bus_load_dp; wire [0:0] bus_load_dp;
wire [0:0] bus_read_pc;
wire [0:0] bus_write_dp;
wire [3:0] bus_nibble_in; wire [3:0] bus_nibble_in;
wire [3:0] bus_nibble_out; wire [3:0] bus_nibble_out;
@ -241,6 +247,8 @@ saturn_bus_ctrl m_bus_ctrl (
.i_address (bus_address), .i_address (bus_address),
.i_load_pc (bus_load_pc), .i_load_pc (bus_load_pc),
.i_load_dp (bus_load_dp), .i_load_dp (bus_load_dp),
.i_read_pc (bus_read_pc),
.i_write_dp (bus_write_dp),
.i_nibble (bus_nibble_out), .i_nibble (bus_nibble_out),
.o_nibble (bus_nibble_in) .o_nibble (bus_nibble_in)
); );
@ -313,7 +321,6 @@ always @(posedge clk) begin
ck_alu_save <= clk_phase[1:0] == `PH_ALU_SAVE; ck_alu_save <= clk_phase[1:0] == `PH_ALU_SAVE;
cycle_ctr <= cycle_ctr + { {31{1'b0}}, (clk_phase[1:0] == `PH_BUS_SEND) }; cycle_ctr <= cycle_ctr + { {31{1'b0}}, (clk_phase[1:0] == `PH_BUS_SEND) };
// stop after 50 clocks
if (cycle_ctr == (max_cycle + 1)) begin if (cycle_ctr == (max_cycle + 1)) begin
$display(".-------------------."); $display(".-------------------.");
$display("| OUT OF CYCLES |"); $display("| OUT OF CYCLES |");
@ -340,7 +347,7 @@ always @(posedge clk) begin
clock_end <= 0; clock_end <= 0;
cycle_ctr <= ~0; cycle_ctr <= ~0;
max_cycle <= 20; max_cycle <= 155;
mem_ctrl_stall <= 0; mem_ctrl_stall <= 0;
`ifndef SIM `ifndef SIM

View file

@ -8,7 +8,8 @@
`include "def-alu.v" `include "def-alu.v"
module saturn_decoder( module saturn_decoder(
i_clk, i_reset, i_cycles, i_en_dbg, i_en_dec, i_stalled, i_clk, i_reset, i_cycles, i_en_dbg, i_en_dec,
i_bus_load_pc, i_stalled,
i_pc, i_nibble, i_pc, i_nibble,
i_reg_p, i_reg_p,
@ -41,26 +42,27 @@ module saturn_decoder(
input wire [0:0] i_clk; input wire [0:0] i_clk;
input wire [0:0] i_reset; input wire [0:0] i_reset;
input wire [31:0] i_cycles; input wire [31:0] i_cycles;
input wire i_en_dbg; input wire [0:0] i_en_dbg;
input wire i_en_dec; input wire [0:0] i_en_dec;
input wire i_stalled; input wire [0:0] i_bus_load_pc;
input wire [0:0] i_stalled;
input wire [19:0] i_pc; input wire [19:0] i_pc;
input wire [3:0] i_nibble; input wire [3:0] i_nibble;
input wire [3:0] i_reg_p; input wire [3:0] i_reg_p;
output reg o_inc_pc; output reg [0:0] o_inc_pc;
output reg o_push; output reg [0:0] o_push;
output reg o_pop; output reg [0:0] o_pop;
output reg o_dec_error; output reg [0:0] o_dec_error;
`ifdef SIM `ifdef SIM
output reg [0:0] o_unimplemented; output reg [0:0] o_unimplemented;
`endif `endif
output reg o_alu_debug; output reg [0:0] o_alu_debug;
// instructions related outputs // instructions related outputs
output reg [19:0] o_ins_addr; output reg [19:0] o_ins_addr;
output reg o_ins_decoded; output reg [0:0] o_ins_decoded;
output reg [1:0] o_fields_table; output reg [1:0] o_fields_table;
output reg [3:0] o_field; output reg [3:0] o_field;
@ -76,20 +78,20 @@ output reg [4:0] o_reg_src1;
output reg [4:0] o_reg_src2; output reg [4:0] o_reg_src2;
// rtn specific // rtn specific
output reg o_ins_rtn; output reg [0:0] o_ins_rtn;
output reg o_set_xm; output reg [0:0] o_set_xm;
output reg o_set_carry; output reg [0:0] o_set_carry;
output reg o_test_carry; output reg [0:0] o_test_carry;
output reg o_carry_val; output reg [0:0] o_carry_val;
output reg o_en_intr; output reg [0:0] o_en_intr;
// setdec/hex // setdec/hex
output reg o_ins_set_mode; output reg [0:0] o_ins_set_mode;
output reg o_mode_dec; output reg [0:0] o_mode_dec;
// alu_operations // alu_operations
output reg o_ins_alu_op; output reg [0:0] o_ins_alu_op;
output reg o_ins_test_go; output reg [0:0] o_ins_test_go;
/* data used by the debugger /* data used by the debugger
* *
@ -434,6 +436,7 @@ always @(posedge i_clk) begin
block_13x <= 1; block_13x <= 1;
4'h4, 4'h5: // DAT[01]=[AC] <field> 4'h4, 4'h5: // DAT[01]=[AC] <field>
begin begin
o_alu_debug <= 0;
`ifdef SIM `ifdef SIM
$display("block_1x %h | use table <= %b", i_nibble, i_nibble[0]); $display("block_1x %h | use table <= %b", i_nibble, i_nibble[0]);
`endif `endif

View file

@ -8,7 +8,7 @@ wire [19:0] new_pc;
assign new_pc = i_pc + 1; assign new_pc = i_pc + 1;
wire run_debugger; wire run_debugger;
assign run_debugger = !i_reset && i_en_dbg && !i_stalled && !next_nibble; assign run_debugger = !i_reset && i_en_dbg && !i_stalled && !i_bus_load_pc && !next_nibble;
wire is_short_transfer; wire is_short_transfer;
assign is_short_transfer = (o_field_last == 3) && assign is_short_transfer = (o_field_last == 3) &&