mirror of
https://github.com/sxpert/hp-saturn
synced 2025-01-31 19:57:50 +01:00
start implementing the bus controller
This commit is contained in:
parent
500e013bf5
commit
128921c364
5 changed files with 131 additions and 64 deletions
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
`define PH_BUS_SEND 0
|
`define PH_BUS_SEND 0
|
||||||
`define PH_BUS_RECV 1
|
`define PH_BUS_RECV 1
|
||||||
|
`define PH_BUS_ECMD 3
|
||||||
|
|
||||||
`define PH_INST_DEC 2
|
`define PH_INST_DEC 2
|
||||||
`define PH_INST_EXE 3
|
`define PH_INST_EXE 3
|
||||||
|
|
|
@ -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-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 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 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
|
|
@ -247,7 +247,8 @@ assign alu_active = !i_reset && !i_stalled;
|
||||||
`ifdef SIM
|
`ifdef SIM
|
||||||
wire do_reg_dump;
|
wire do_reg_dump;
|
||||||
wire do_alu_shpc;
|
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;
|
assign do_alu_shpc = alu_active && i_en_alu_dump;
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ module saturn_bus_ctrl (
|
||||||
i_cycle_ctr,
|
i_cycle_ctr,
|
||||||
i_en_bus_send,
|
i_en_bus_send,
|
||||||
i_en_bus_recv,
|
i_en_bus_recv,
|
||||||
|
i_en_bus_ecmd,
|
||||||
i_stalled,
|
i_stalled,
|
||||||
i_read_stall,
|
i_read_stall,
|
||||||
|
|
||||||
|
@ -36,8 +37,10 @@ input wire [0:0] i_reset;
|
||||||
input wire [31:0] i_cycle_ctr;
|
input wire [31:0] i_cycle_ctr;
|
||||||
input wire [0:0] i_en_bus_send;
|
input wire [0:0] i_en_bus_send;
|
||||||
input wire [0:0] i_en_bus_recv;
|
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_stalled;
|
||||||
input wire [0:0] i_read_stall;
|
input wire [0:0] i_read_stall;
|
||||||
|
|
||||||
output reg [0:0] o_stalled_by_bus;
|
output reg [0:0] o_stalled_by_bus;
|
||||||
|
|
||||||
input wire [3:0] i_bus_data;
|
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;
|
assign en_bus_send = i_en_bus_send && !i_stalled;
|
||||||
wire en_bus_recv;
|
wire en_bus_recv;
|
||||||
assign en_bus_recv = i_en_bus_recv && !i_stalled;
|
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...
|
* test rom...
|
||||||
|
@ -77,31 +82,85 @@ initial begin
|
||||||
`ifdef SIM
|
`ifdef SIM
|
||||||
$readmemh("rom-gx-r.hex", rom);
|
$readmemh("rom-gx-r.hex", rom);
|
||||||
// $readmemh( "testrom-2.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
|
`endif
|
||||||
end
|
end
|
||||||
|
|
||||||
|
reg [2:0] addr_cnt;
|
||||||
|
|
||||||
|
reg [0:0] send_addr;
|
||||||
|
|
||||||
|
reg [19:0] local_pc;
|
||||||
|
|
||||||
always @(posedge i_clk) begin
|
always @(posedge i_clk) begin
|
||||||
if (i_reset)
|
if (i_reset) begin
|
||||||
o_stalled_by_bus <= 0;
|
o_stalled_by_bus <= 0;
|
||||||
|
o_bus_strobe <= 0;
|
||||||
if (en_bus_send) begin
|
o_bus_cmd_data <= 1; // 1 is the default level
|
||||||
if (i_load_pc) begin
|
addr_cnt <= 0;
|
||||||
$display("BUS_SEND %0d: loading pc %h", `PH_BUS_SEND, i_address);
|
|
||||||
|
|
||||||
o_stalled_by_bus <= 1;
|
|
||||||
end
|
|
||||||
o_bus_strobe <= 1;
|
|
||||||
end
|
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
|
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]]);
|
$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]];
|
o_nibble <= rom[i_alu_pc[`ROMBITS-1:0]];
|
||||||
end
|
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_strobe <= 0;
|
||||||
|
o_bus_cmd_data <= 1;
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
109
saturn_core.v
109
saturn_core.v
|
@ -46,19 +46,20 @@ assign reset = btn[1];
|
||||||
reg [1:0] clk_phase;
|
reg [1:0] clk_phase;
|
||||||
reg [0:0] en_reset;
|
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] ck_bus_send; // phase 0
|
||||||
reg [0:0] en_bus_recv; // phase 1
|
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] ck_inst_dec; // phase 2
|
||||||
reg [0:0] en_inst_exe; // phase 3
|
reg [0:0] ck_inst_exe; // phase 3
|
||||||
|
|
||||||
reg [0:0] en_alu_dump; // phase 0
|
reg [0:0] ck_alu_dump; // phase 0
|
||||||
reg [0:0] en_alu_init; // phase 3
|
reg [0:0] ck_alu_init; // phase 3
|
||||||
reg [0:0] en_alu_prep; // phase 1
|
reg [0:0] ck_alu_prep; // phase 1
|
||||||
reg [0:0] en_alu_calc; // phase 2
|
reg [0:0] ck_alu_calc; // phase 2
|
||||||
reg [0:0] en_alu_save; // phase 3
|
reg [0:0] ck_alu_save; // phase 3
|
||||||
|
|
||||||
reg [0:0] clock_end;
|
reg [0:0] clock_end;
|
||||||
reg [31:0] cycle_ctr;
|
reg [31:0] cycle_ctr;
|
||||||
|
@ -82,8 +83,8 @@ saturn_decoder m_decoder (
|
||||||
.i_clk (clk),
|
.i_clk (clk),
|
||||||
.i_reset (reset),
|
.i_reset (reset),
|
||||||
.i_cycles (cycle_ctr),
|
.i_cycles (cycle_ctr),
|
||||||
.i_en_dbg (en_debugger),
|
.i_en_dbg (ck_debugger),
|
||||||
.i_en_dec (en_inst_dec),
|
.i_en_dec (ck_inst_dec),
|
||||||
.i_pc (reg_pc),
|
.i_pc (reg_pc),
|
||||||
.i_stalled (dec_stalled),
|
.i_stalled (dec_stalled),
|
||||||
.i_nibble (bus_nibble_in),
|
.i_nibble (bus_nibble_in),
|
||||||
|
@ -155,11 +156,11 @@ 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_en_alu_dump (en_alu_dump),
|
.i_en_alu_dump (ck_alu_dump),
|
||||||
.i_en_alu_prep (en_alu_prep),
|
.i_en_alu_prep (ck_alu_prep),
|
||||||
.i_en_alu_calc (en_alu_calc),
|
.i_en_alu_calc (ck_alu_calc),
|
||||||
.i_en_alu_init (en_alu_init),
|
.i_en_alu_init (ck_alu_init),
|
||||||
.i_en_alu_save (en_alu_save),
|
.i_en_alu_save (ck_alu_save),
|
||||||
.i_stalled (alu_stalled),
|
.i_stalled (alu_stalled),
|
||||||
|
|
||||||
.o_bus_address (bus_address),
|
.o_bus_address (bus_address),
|
||||||
|
@ -222,8 +223,9 @@ saturn_bus_ctrl m_bus_ctrl (
|
||||||
.i_clk (clk),
|
.i_clk (clk),
|
||||||
.i_reset (reset),
|
.i_reset (reset),
|
||||||
.i_cycle_ctr (cycle_ctr),
|
.i_cycle_ctr (cycle_ctr),
|
||||||
.i_en_bus_send (en_bus_send),
|
.i_en_bus_send (ck_bus_send),
|
||||||
.i_en_bus_recv (en_bus_recv),
|
.i_en_bus_recv (ck_bus_recv),
|
||||||
|
.i_en_bus_ecmd (ck_bus_ecmd),
|
||||||
.i_stalled (mem_ctrl_stall),
|
.i_stalled (mem_ctrl_stall),
|
||||||
.i_read_stall (dec_stalled),
|
.i_read_stall (dec_stalled),
|
||||||
.o_stalled_by_bus (bus_stalls_core),
|
.o_stalled_by_bus (bus_stalls_core),
|
||||||
|
@ -256,19 +258,20 @@ wire [0:0] bus_cmd_data;
|
||||||
initial begin
|
initial begin
|
||||||
clk_phase = 0;
|
clk_phase = 0;
|
||||||
|
|
||||||
en_debugger = 0; // phase 0
|
ck_debugger = 0; // phase 0
|
||||||
|
|
||||||
en_bus_send = 0; // phase 0
|
ck_bus_send = 0; // phase 0
|
||||||
en_bus_recv = 0; // phase 1
|
ck_bus_recv = 0; // phase 1
|
||||||
|
ck_bus_ecmd = 0; // phase 3
|
||||||
|
|
||||||
en_inst_dec = 0; // phase 2
|
ck_inst_dec = 0; // phase 2
|
||||||
en_inst_exe = 0; // phase 3
|
ck_inst_exe = 0; // phase 3
|
||||||
|
|
||||||
en_alu_dump = 0;
|
ck_alu_dump = 0;
|
||||||
en_alu_prep = 0; // phase 1
|
ck_alu_prep = 0; // phase 1
|
||||||
en_alu_calc = 0; // phase 2
|
ck_alu_calc = 0; // phase 2
|
||||||
en_alu_init = 0; // phase 0
|
ck_alu_init = 0; // phase 0
|
||||||
en_alu_save = 0; // phase 3
|
ck_alu_save = 0; // phase 3
|
||||||
|
|
||||||
clock_end = 0;
|
clock_end = 0;
|
||||||
cycle_ctr = 0;
|
cycle_ctr = 0;
|
||||||
|
@ -294,19 +297,20 @@ initial begin
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
if (!reset) begin
|
if (!reset) begin
|
||||||
clk_phase <= clk_phase + 1;
|
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;
|
ck_bus_send <= clk_phase[1:0] == `PH_BUS_SEND;
|
||||||
en_bus_recv <= clk_phase[1:0] == `PH_BUS_RECV;
|
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;
|
ck_inst_dec <= clk_phase[1:0] == `PH_INST_DEC;
|
||||||
en_inst_exe <= clk_phase[1:0] == `PH_INST_EXE;
|
ck_inst_exe <= clk_phase[1:0] == `PH_INST_EXE;
|
||||||
|
|
||||||
en_alu_dump <= clk_phase[1:0] == `PH_ALU_DUMP;
|
ck_alu_dump <= clk_phase[1:0] == `PH_ALU_DUMP;
|
||||||
en_alu_init <= clk_phase[1:0] == `PH_ALU_INIT;
|
ck_alu_init <= clk_phase[1:0] == `PH_ALU_INIT;
|
||||||
en_alu_prep <= clk_phase[1:0] == `PH_ALU_PREP;
|
ck_alu_prep <= clk_phase[1:0] == `PH_ALU_PREP;
|
||||||
en_alu_calc <= clk_phase[1:0] == `PH_ALU_CALC;
|
ck_alu_calc <= clk_phase[1:0] == `PH_ALU_CALC;
|
||||||
en_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
|
// stop after 50 clocks
|
||||||
|
@ -319,19 +323,20 @@ always @(posedge clk) begin
|
||||||
end else begin
|
end else begin
|
||||||
clk_phase <= ~0;
|
clk_phase <= ~0;
|
||||||
|
|
||||||
en_debugger <= 0;
|
ck_debugger <= 0;
|
||||||
|
|
||||||
en_bus_send <= 0;
|
ck_bus_send <= 0;
|
||||||
en_bus_recv <= 0;
|
ck_bus_recv <= 0;
|
||||||
|
ck_bus_ecmd <= 0;
|
||||||
|
|
||||||
en_inst_dec <= 0;
|
ck_inst_dec <= 0;
|
||||||
en_inst_exe <= 0;
|
ck_inst_exe <= 0;
|
||||||
|
|
||||||
en_alu_dump <= 0;
|
ck_alu_dump <= 0;
|
||||||
en_alu_init <= 0;
|
ck_alu_init <= 0;
|
||||||
en_alu_prep <= 0;
|
ck_alu_prep <= 0;
|
||||||
en_alu_calc <= 0;
|
ck_alu_calc <= 0;
|
||||||
en_alu_save <= 0;
|
ck_alu_save <= 0;
|
||||||
|
|
||||||
clock_end <= 0;
|
clock_end <= 0;
|
||||||
cycle_ctr <= ~0;
|
cycle_ctr <= ~0;
|
||||||
|
@ -356,11 +361,11 @@ assign dec_stalled = alu_stalls_dec || bus_stalls_core;
|
||||||
assign alu_stalled = bus_stalls_core;
|
assign alu_stalled = bus_stalls_core;
|
||||||
|
|
||||||
wire read_nibble_to_dec;
|
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;
|
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;
|
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;
|
assign halt = clock_end || inv_opcode;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue