start implementing the bus controller

This commit is contained in:
Raphael Jacquot 2019-02-17 08:35:26 +01:00
parent 500e013bf5
commit 128921c364
5 changed files with 131 additions and 64 deletions

View file

@ -6,6 +6,7 @@
`define PH_BUS_SEND 0
`define PH_BUS_RECV 1
`define PH_BUS_ECMD 3
`define PH_INST_DEC 2
`define PH_INST_EXE 3

View file

@ -33,3 +33,4 @@ 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

View file

@ -247,7 +247,8 @@ assign alu_active = !i_reset && !i_stalled;
`ifdef SIM
wire do_reg_dump;
wire do_alu_shpc;
assign do_reg_dump = alu_active && i_en_alu_dump && i_ins_decoded && !o_alu_stall_dec;
assign do_reg_dump = alu_active && i_en_alu_dump && !o_bus_load_pc &&
i_ins_decoded && !o_alu_stall_dec;
assign do_alu_shpc = alu_active && i_en_alu_dump;
`endif

View file

@ -11,6 +11,7 @@ module saturn_bus_ctrl (
i_cycle_ctr,
i_en_bus_send,
i_en_bus_recv,
i_en_bus_ecmd,
i_stalled,
i_read_stall,
@ -36,8 +37,10 @@ input wire [0:0] i_reset;
input wire [31:0] i_cycle_ctr;
input wire [0:0] i_en_bus_send;
input wire [0:0] i_en_bus_recv;
input wire [0:0] i_en_bus_ecmd;
input wire [0:0] i_stalled;
input wire [0:0] i_read_stall;
output reg [0:0] o_stalled_by_bus;
input wire [3:0] i_bus_data;
@ -61,6 +64,8 @@ wire en_bus_send;
assign en_bus_send = i_en_bus_send && !i_stalled;
wire en_bus_recv;
assign en_bus_recv = i_en_bus_recv && !i_stalled;
wire en_bus_ecmd;
assign en_bus_ecmd = i_en_bus_ecmd && !i_stalled;
/*
* test rom...
@ -77,31 +82,85 @@ initial begin
`ifdef SIM
$readmemh("rom-gx-r.hex", rom);
// $readmemh( "testrom-2.hex", rom);
// $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);
`endif
end
reg [2:0] addr_cnt;
reg [0:0] send_addr;
reg [19:0] local_pc;
always @(posedge i_clk) begin
if (i_reset)
if (i_reset) begin
o_stalled_by_bus <= 0;
if (en_bus_send) begin
if (i_load_pc) begin
$display("BUS_SEND %0d: loading pc %h", `PH_BUS_SEND, i_address);
o_stalled_by_bus <= 1;
end
o_bus_strobe <= 1;
o_bus_strobe <= 0;
o_bus_cmd_data <= 1; // 1 is the default level
addr_cnt <= 0;
end
/*
*
* sending commands or data to the bus
*
*/
if (en_bus_send) begin
if (i_load_pc) begin
$display("BUS_SEND %0d: loading pc %h", `PH_BUS_SEND, i_address);
o_bus_data <= `BUSCMD_LOAD_PC;
end
if (i_load_dp) begin
$display("BUS_SEND %0d: loading dp %h", `PH_BUS_SEND, i_address);
o_bus_data <= `BUSCMD_LOAD_DP;
end
if (i_load_pc || i_load_dp) begin
o_stalled_by_bus <= 1;
o_bus_cmd_data <= 0;
addr_cnt <= 0;
send_addr <= 1;
end
if (send_addr) begin
$display("BUS_SEND %0d: send addr nibble %0d [%h]", `PH_BUS_SEND, addr_cnt, i_address[addr_cnt*4+:4]);
o_bus_data <= i_address[addr_cnt*4+:4];
addr_cnt <= addr_cnt + 1;
end
if (!i_read_stall || send_addr)
o_bus_strobe <= 1;
end
if (en_bus_ecmd && send_addr && (addr_cnt == 5)) begin
$display("BUS_ECMD %0d: releasing stall after sending addr", `PH_BUS_ECMD);
send_addr <= 0;
o_stalled_by_bus = 0;
end
/*
*
* reading data from the bus
*
*/
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]]);
o_nibble <= rom[i_alu_pc[`ROMBITS-1:0]];
end
// this is always done to lower the strobe signal
if (en_bus_recv)
/*
*
* resets the bus automatically
*
*/
if (en_bus_recv) begin
o_bus_strobe <= 0;
o_bus_cmd_data <= 1;
end
end
endmodule

View file

@ -46,19 +46,20 @@ assign reset = btn[1];
reg [1:0] clk_phase;
reg [0:0] en_reset;
reg [0:0] en_debugger; // phase 0
reg [0:0] ck_debugger; // phase 0
reg [0:0] en_bus_send; // phase 0
reg [0:0] en_bus_recv; // phase 1
reg [0:0] ck_bus_send; // phase 0
reg [0:0] ck_bus_recv; // phase 1
reg [0:0] ck_bus_ecmd; // phase 3
reg [0:0] en_inst_dec; // phase 2
reg [0:0] en_inst_exe; // phase 3
reg [0:0] ck_inst_dec; // phase 2
reg [0:0] ck_inst_exe; // phase 3
reg [0:0] en_alu_dump; // phase 0
reg [0:0] en_alu_init; // phase 3
reg [0:0] en_alu_prep; // phase 1
reg [0:0] en_alu_calc; // phase 2
reg [0:0] en_alu_save; // phase 3
reg [0:0] ck_alu_dump; // phase 0
reg [0:0] ck_alu_init; // phase 3
reg [0:0] ck_alu_prep; // phase 1
reg [0:0] ck_alu_calc; // phase 2
reg [0:0] ck_alu_save; // phase 3
reg [0:0] clock_end;
reg [31:0] cycle_ctr;
@ -82,8 +83,8 @@ saturn_decoder m_decoder (
.i_clk (clk),
.i_reset (reset),
.i_cycles (cycle_ctr),
.i_en_dbg (en_debugger),
.i_en_dec (en_inst_dec),
.i_en_dbg (ck_debugger),
.i_en_dec (ck_inst_dec),
.i_pc (reg_pc),
.i_stalled (dec_stalled),
.i_nibble (bus_nibble_in),
@ -155,11 +156,11 @@ wire [0:0] ins_test_go;
saturn_alu m_alu (
.i_clk (clk),
.i_reset (reset),
.i_en_alu_dump (en_alu_dump),
.i_en_alu_prep (en_alu_prep),
.i_en_alu_calc (en_alu_calc),
.i_en_alu_init (en_alu_init),
.i_en_alu_save (en_alu_save),
.i_en_alu_dump (ck_alu_dump),
.i_en_alu_prep (ck_alu_prep),
.i_en_alu_calc (ck_alu_calc),
.i_en_alu_init (ck_alu_init),
.i_en_alu_save (ck_alu_save),
.i_stalled (alu_stalled),
.o_bus_address (bus_address),
@ -222,8 +223,9 @@ saturn_bus_ctrl m_bus_ctrl (
.i_clk (clk),
.i_reset (reset),
.i_cycle_ctr (cycle_ctr),
.i_en_bus_send (en_bus_send),
.i_en_bus_recv (en_bus_recv),
.i_en_bus_send (ck_bus_send),
.i_en_bus_recv (ck_bus_recv),
.i_en_bus_ecmd (ck_bus_ecmd),
.i_stalled (mem_ctrl_stall),
.i_read_stall (dec_stalled),
.o_stalled_by_bus (bus_stalls_core),
@ -256,19 +258,20 @@ wire [0:0] bus_cmd_data;
initial begin
clk_phase = 0;
en_debugger = 0; // phase 0
ck_debugger = 0; // phase 0
en_bus_send = 0; // phase 0
en_bus_recv = 0; // phase 1
ck_bus_send = 0; // phase 0
ck_bus_recv = 0; // phase 1
ck_bus_ecmd = 0; // phase 3
en_inst_dec = 0; // phase 2
en_inst_exe = 0; // phase 3
ck_inst_dec = 0; // phase 2
ck_inst_exe = 0; // phase 3
en_alu_dump = 0;
en_alu_prep = 0; // phase 1
en_alu_calc = 0; // phase 2
en_alu_init = 0; // phase 0
en_alu_save = 0; // phase 3
ck_alu_dump = 0;
ck_alu_prep = 0; // phase 1
ck_alu_calc = 0; // phase 2
ck_alu_init = 0; // phase 0
ck_alu_save = 0; // phase 3
clock_end = 0;
cycle_ctr = 0;
@ -294,19 +297,20 @@ initial begin
always @(posedge clk) begin
if (!reset) begin
clk_phase <= clk_phase + 1;
en_debugger <= clk_phase[1:0] == `PH_DEBUGGER;
ck_debugger <= clk_phase[1:0] == `PH_DEBUGGER;
en_bus_send <= clk_phase[1:0] == `PH_BUS_SEND;
en_bus_recv <= clk_phase[1:0] == `PH_BUS_RECV;
ck_bus_send <= clk_phase[1:0] == `PH_BUS_SEND;
ck_bus_recv <= clk_phase[1:0] == `PH_BUS_RECV;
ck_bus_ecmd <= clk_phase[1:0] == `PH_BUS_ECMD;
en_inst_dec <= clk_phase[1:0] == `PH_INST_DEC;
en_inst_exe <= clk_phase[1:0] == `PH_INST_EXE;
ck_inst_dec <= clk_phase[1:0] == `PH_INST_DEC;
ck_inst_exe <= clk_phase[1:0] == `PH_INST_EXE;
en_alu_dump <= clk_phase[1:0] == `PH_ALU_DUMP;
en_alu_init <= clk_phase[1:0] == `PH_ALU_INIT;
en_alu_prep <= clk_phase[1:0] == `PH_ALU_PREP;
en_alu_calc <= clk_phase[1:0] == `PH_ALU_CALC;
en_alu_save <= clk_phase[1:0] == `PH_ALU_SAVE;
ck_alu_dump <= clk_phase[1:0] == `PH_ALU_DUMP;
ck_alu_init <= clk_phase[1:0] == `PH_ALU_INIT;
ck_alu_prep <= clk_phase[1:0] == `PH_ALU_PREP;
ck_alu_calc <= clk_phase[1:0] == `PH_ALU_CALC;
ck_alu_save <= clk_phase[1:0] == `PH_ALU_SAVE;
cycle_ctr <= cycle_ctr + { {31{1'b0}}, (clk_phase[1:0] == `PH_BUS_SEND) };
// stop after 50 clocks
@ -319,19 +323,20 @@ always @(posedge clk) begin
end else begin
clk_phase <= ~0;
en_debugger <= 0;
ck_debugger <= 0;
en_bus_send <= 0;
en_bus_recv <= 0;
ck_bus_send <= 0;
ck_bus_recv <= 0;
ck_bus_ecmd <= 0;
en_inst_dec <= 0;
en_inst_exe <= 0;
ck_inst_dec <= 0;
ck_inst_exe <= 0;
en_alu_dump <= 0;
en_alu_init <= 0;
en_alu_prep <= 0;
en_alu_calc <= 0;
en_alu_save <= 0;
ck_alu_dump <= 0;
ck_alu_init <= 0;
ck_alu_prep <= 0;
ck_alu_calc <= 0;
ck_alu_save <= 0;
clock_end <= 0;
cycle_ctr <= ~0;
@ -356,11 +361,11 @@ assign dec_stalled = alu_stalls_dec || bus_stalls_core;
assign alu_stalled = bus_stalls_core;
wire read_nibble_to_dec;
assign read_nibble_to_dec = en_bus_recv && !dec_stalled;
assign read_nibble_to_dec = ck_bus_recv && !dec_stalled;
wire dec_stalled_no_read;
assign dec_stalled_no_read = en_bus_recv && !bus_stalls_core && dec_stalled;
assign dec_stalled_no_read = ck_bus_recv && !bus_stalls_core && dec_stalled;
wire bus_is_stalled;
assign bus_is_stalled = en_bus_recv && bus_stalls_core;
assign bus_is_stalled = ck_bus_recv && bus_stalls_core;
assign halt = clock_end || inv_opcode;