implement the reset bus command

This commit is contained in:
Raphael Jacquot 2019-02-17 15:03:36 +01:00
parent 1c719a1828
commit 7a3a36bd25
7 changed files with 106 additions and 35 deletions

View file

@ -33,4 +33,5 @@ second delay is posedge $glbnet$clk -> <async>
2019-02-15 17:12 1544 70.76MHz 33.39ns 12.77ns 10374 75.73MHz 16.74ns 3.99ns
2019-02-16 11:18 1552 72.00MHz 34.10ns 10.85ns 10072 75.65MHz 17.35ns 3.46ns
2019-02-16 12:18 1453 62.31MHz 33.86ns 12.05ns 10323 70.66MHz 16.96ns 3.59ns
2019-02-16 22:54 1629 60.66MHz 33.62ns 12.05ns 11562 56.91MHz 17.11ns 3.84ns
2019-02-16 22:54 1629 60.66MHz 33.62ns 12.05ns 11562 56.91MHz 17.11ns 3.84ns
2019-02-17 12:58 1679 68.43MHz 38.91ns 12.77ns 10906 70.19MHz 18.76ns 4.00ns

View file

@ -730,8 +730,10 @@ always @(posedge i_clk) begin
if (i_reset)
just_reset <= 1;
if (just_reset)
if (just_reset && do_alu_pc) begin
just_reset <= 0;
$display("---------------------------------------- CLEARING JUST_RESET");
end
end
@ -763,15 +765,12 @@ always @(posedge i_clk) begin
// reset stuff
if (i_reset) begin
write_done <= 0;
extra_cycles <= 0;
o_bus_load_dp <= 0;
o_bus_write_dp <= 0;
end
// just reset is managed below
if (just_reset)
o_bus_read_pc <= 1;
// setup the order to load DP in time
if (setup_load_dp) begin
o_bus_load_dp <= 1;

View file

@ -30,6 +30,7 @@ module saturn_bus_ctrl (
i_load_dp,
i_read_pc,
i_write_dp,
i_cmd_reset,
i_nibble,
o_nibble
);
@ -56,6 +57,7 @@ input wire [0:0] i_load_pc;
input wire [0:0] i_load_dp;
input wire [0:0] i_read_pc;
input wire [0:0] i_write_dp;
input wire [0:0] i_cmd_reset;
input wire [3:0] i_nibble;
output reg [3:0] o_nibble;
@ -96,15 +98,21 @@ end
reg [3:0] last_cmd;
reg [2:0] addr_cnt;
reg [0:0] send_addr;
reg [0:0] reset_sent;
reg [0:0] send_pc_read;
reg [19:0] local_pc;
reg [19:0] local_dp;
always @(posedge i_clk) begin
if (i_reset) begin
last_cmd <= 0;
o_stalled_by_bus <= 0;
o_bus_strobe <= 0;
o_bus_cmd_data <= 1; // 1 is the default level
addr_cnt <= 0;
send_addr <= 0;
reset_sent <= 0;
send_pc_read <= 0;
end
/*
@ -152,12 +160,14 @@ always @(posedge i_clk) begin
* after a data transfer
*/
if (i_read_pc) begin
if (i_read_pc || send_pc_read) 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;
send_pc_read <= 0;
end
o_bus_strobe <= 1;
end
@ -182,26 +192,16 @@ always @(posedge i_clk) begin
end
end
if (i_cmd_reset && !reset_sent) begin
$display("BUS_SEND %0d: [%d] RESET", `PH_BUS_SEND, i_cycle_ctr);
o_bus_data <= `BUSCMD_RESET;
last_cmd <= `BUSCMD_RESET;
reset_sent <= 1;
o_bus_strobe <= 1;
end
end
if (en_bus_ecmd && send_addr && (addr_cnt == 5)) begin
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;
o_stalled_by_bus <= 0;
end
/*
*
* reading data from the bus
@ -209,25 +209,79 @@ always @(posedge i_clk) begin
*/
if (en_bus_recv && !i_read_stall) begin
if (last_cmd == `BUSCMD_PC_READ) begin
$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
if (en_bus_recv) begin
if (!i_read_stall)
case (last_cmd)
`BUSCMD_PC_READ: begin
$display("BUS_RECV %0d: [%d] <= READ [%5h] %h", `PH_BUS_RECV, i_cycle_ctr, local_pc, rom[local_pc[`ROMBITS-1:0]]);
o_nibble <= rom[local_pc[`ROMBITS-1:0]];
local_pc <= local_pc + 1;
end
endcase
else
if (!o_stalled_by_bus) begin
$write("BUS_RECV %0d: [%d] STALLED (last ", `PH_BUS_RECV, i_cycle_ctr);
case (last_cmd)
`BUSCMD_PC_READ: $write("PC_READ");
`BUSCMD_RESET: $write("RESET");
default: $write("%h", last_cmd);
endcase
$display(")");
end
/*
*
* resets the bus automatically
*
*/
if (en_bus_recv) begin
o_bus_strobe <= 0;
o_bus_cmd_data <= 1;
end
// command automatic switchover
if (en_bus_ecmd) begin
if (i_cmd_reset && !reset_sent)
o_stalled_by_bus <= 1;
case (last_cmd)
`BUSCMD_LOAD_PC,
`BUSCMD_LOAD_DP:
if (send_addr && (addr_cnt == 5)) begin
$display("BUS_ECMD %0d: [%d] <= %sC_READ mode",
`PH_BUS_ECMD, i_cycle_ctr,
(last_cmd == `BUSCMD_LOAD_PC)?"P":"D");
last_cmd <= (last_cmd == `BUSCMD_LOAD_PC)?`BUSCMD_PC_READ:`BUSCMD_DP_READ;
case (last_cmd)
`BUSCMD_LOAD_PC: local_pc <= i_address;
`BUSCMD_LOAD_DP: local_dp <= i_address;
endcase
send_addr <= 0;
o_stalled_by_bus <= 0;
end
`BUSCMD_PC_READ: begin
if (o_stalled_by_bus && reset_sent) begin
// $display("BUS_ECMD %0d: [%d] (pc_read unstall)", `PH_BUS_ECMD, i_cycle_ctr);
o_stalled_by_bus <= 0;
end
end
`BUSCMD_RESET: begin
if (o_stalled_by_bus && reset_sent) begin
// $display("BUS_ECMD %0d: [%d] (reset, send pc_read)", `PH_BUS_ECMD, i_cycle_ctr);
send_pc_read <= 1;
end
end
endcase
end
end
endmodule

View file

@ -120,7 +120,8 @@ saturn_decoder m_decoder (
.o_ins_set_mode (ins_set_mode),
.o_mode_dec (mode_dec),
.o_ins_alu_op (ins_alu_op),
.o_ins_test_go (ins_test_go)
.o_ins_test_go (ins_test_go),
.o_ins_reset (ins_reset)
);
wire [0:0] inc_pc;
@ -152,6 +153,7 @@ wire [0:0] ins_set_mode;
wire [0:0] mode_dec;
wire [0:0] ins_alu_op;
wire [0:0] ins_test_go;
wire [0:0] ins_reset;
saturn_alu m_alu (
@ -249,6 +251,7 @@ saturn_bus_ctrl m_bus_ctrl (
.i_load_dp (bus_load_dp),
.i_read_pc (bus_read_pc),
.i_write_dp (bus_write_dp),
.i_cmd_reset (ins_reset),
.i_nibble (bus_nibble_out),
.o_nibble (bus_nibble_in)
);

View file

@ -32,6 +32,7 @@ module saturn_decoder(
o_set_carry, o_test_carry, o_carry_val,
o_ins_set_mode, o_mode_dec,
o_ins_alu_op, o_ins_test_go,
o_ins_reset,
o_dbg_nibbles, o_dbg_nb_nbls, o_mem_load, o_mem_pos
);
@ -93,6 +94,9 @@ output reg [0:0] o_mode_dec;
output reg [0:0] o_ins_alu_op;
output reg [0:0] o_ins_test_go;
// bus operations
output reg [0:0] o_ins_reset;
/* data used by the debugger
*
*/
@ -183,6 +187,8 @@ always @(posedge i_clk) begin
o_ins_rtn <= 0;
o_push <= 0;
o_pop <= 0;
o_ins_set_mode <= 0;
o_ins_reset <= 0;
end
if (decoder_active) begin
@ -248,6 +254,9 @@ always @(posedge i_clk) begin
o_ins_alu_op <= 0;
o_ins_test_go <= 0;
// bus instructions
o_ins_reset <= 0;
o_dbg_nb_nbls <= 1;
o_mem_pos <= 0;
@ -265,6 +274,7 @@ always @(posedge i_clk) begin
block_jump_test <= 0;
end else begin
// assign block regs
$display("FIRST NIBBLE %h", i_nibble);
case (i_nibble)
4'h0: block_0x <= 1;
4'h1: block_1x <= 1;

View file

@ -55,6 +55,7 @@
o_ins_decoded <= 1;
end
4'hA: begin // RESET
o_ins_reset <= 1;
next_nibble <= 0;
o_ins_decoded <= 1;
end

View file

@ -67,6 +67,9 @@ always @(posedge i_clk) begin
if (o_ins_set_mode) begin
$write("SET%s", o_mode_dec?"DEC":"HEX");
end
if (o_ins_reset) begin
$write("RESET");
end
if (o_ins_alu_op) begin
case (o_alu_op)