From 128921c364048b960843fe5e6a6c7c52289f33b5 Mon Sep 17 00:00:00 2001 From: Raphael Jacquot Date: Sun, 17 Feb 2019 08:35:26 +0100 Subject: [PATCH] start implementing the bus controller --- def-clocks.v | 1 + history.txt | 1 + saturn_alu.v | 3 +- saturn_bus_ctrl.v | 81 +++++++++++++++++++++++++++++----- saturn_core.v | 109 ++++++++++++++++++++++++---------------------- 5 files changed, 131 insertions(+), 64 deletions(-) diff --git a/def-clocks.v b/def-clocks.v index b05e667..d97966f 100644 --- a/def-clocks.v +++ b/def-clocks.v @@ -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 diff --git a/history.txt b/history.txt index fac2167..15f4842 100644 --- a/history.txt +++ b/history.txt @@ -33,3 +33,4 @@ second delay is posedge $glbnet$clk -> 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 \ No newline at end of file diff --git a/saturn_alu.v b/saturn_alu.v index 20885eb..ff46406 100644 --- a/saturn_alu.v +++ b/saturn_alu.v @@ -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 diff --git a/saturn_bus_ctrl.v b/saturn_bus_ctrl.v index de42ce0..6055c51 100644 --- a/saturn_bus_ctrl.v +++ b/saturn_bus_ctrl.v @@ -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 diff --git a/saturn_core.v b/saturn_core.v index 3b13a38..198e382 100644 --- a/saturn_core.v +++ b/saturn_core.v @@ -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;