implement read from DP

This commit is contained in:
Raphael Jacquot 2019-02-18 07:43:36 +01:00
parent 0a45b014d7
commit 1444baca19
5 changed files with 114 additions and 57 deletions

View file

@ -41,3 +41,4 @@ second delay is posedge $glbnet$clk -> <async>
2019-02-17 21:21 1734 71.16MHz 32.10ns 12.05ns 11359 73.56MHz 17.19ns 3.73ns
2019-02-17 22:31 1573 77.32MHz 32.91ns 12.77ns 10265 70.53MHz 17.35ns 4.13ns
2019-02-17 22:48 1067 69.94MHz 32.87ns 12.77ns 6427 74.33MHz 17.71ns 3.96ns
2019-02-17 23:04 1158 64.11MHz 37.87ns 12.77ns 7149 66.74MHz 19.03ns 4.06ns

View file

@ -26,10 +26,12 @@ module saturn_alu (
o_bus_address,
o_bus_pc_read,
o_bus_dp_read,
o_bus_dp_write,
o_bus_load_pc,
o_bus_load_dp,
o_bus_config,
i_bus_nibble_in,
o_bus_nibble_out,
i_push,
@ -77,10 +79,12 @@ input wire [0:0] i_stalled;
output reg [19:0] o_bus_address;
output reg [0:0] o_bus_pc_read;
output reg [0:0] o_bus_dp_read;
output reg [0:0] o_bus_dp_write;
output reg [0:0] o_bus_load_pc;
output reg [0:0] o_bus_load_dp;
output reg [0:0] o_bus_config;
input wire [3:0] i_bus_nibble_in;
output reg [3:0] o_bus_nibble_out;
input wire [0:0] i_push;
@ -292,7 +296,7 @@ assign do_go_prep = alu_active && i_en_alu_prep && i_ins_test_go;
assign o_alu_stall_dec = (!no_extra_cycles) ||
(alu_run &&
(!i_alu_no_stall || alu_finish || alu_go_test));
(!i_alu_no_stall || alu_finish || alu_go_test || o_bus_dp_read));
wire alu_start;
wire alu_finish;
@ -465,17 +469,6 @@ always @(posedge i_clk) begin
alu_done <= 0;
end
// if (do_alu_save && alu_done)
// case (alu_op)
// `ALU_OP_TEST_EQ,
// `ALU_OP_TEST_NEQ:
// begin
// $display("#### UNBLOCK THE DECODER");
// alu_go_test <= 1;
// end
// endcase
end
@ -519,6 +512,8 @@ always @(posedge i_clk) begin
`ALU_REG_D0: p_src1 <= D0[f_cur*4+:4];
`ALU_REG_D1: p_src1 <= D1[f_cur*4+:4];
`ALU_REG_P: p_src1 <= P;
`ALU_REG_DAT0,
`ALU_REG_DAT1: p_src1 <= i_bus_nibble_in;
`ALU_REG_HST: p_src1 <= HST;
`ALU_REG_IMM: p_src1 <= i_imm_value;
`ALU_REG_ZERO: p_src1 <= 0;
@ -816,26 +811,53 @@ end
reg [0:0] write_done;
reg [1:0] extra_cycles;
wire [0:0] read_done;
wire [0:0] setup_load_dp_read;
wire [0:0] setup_load_dp_write;
wire [0:0] setup_load_dp;
wire [0:0] no_extra_cycles;
wire [1:0] cycles_to_go;
assign setup_load_dp = do_alu_init && is_mem_xfer && !write_done;
assign no_extra_cycles = (extra_cycles == 0);
assign cycles_to_go = extra_cycles - 1;
assign read_done = is_mem_read && do_alu_save && ((f_cur +1) == f_last);
assign setup_load_dp_read = do_alu_init && is_mem_read && !read_done;
assign setup_load_dp_write = do_alu_init && is_mem_write && !write_done;
assign setup_load_dp = setup_load_dp_read || setup_load_dp_write;
assign no_extra_cycles = (extra_cycles == 0);
assign cycles_to_go = extra_cycles - 1;
always @(posedge i_clk) begin
// reset stuff
if (i_reset) begin
// read_done <= 0;
write_done <= 0;
extra_cycles <= 0;
o_bus_load_dp <= 0;
o_bus_dp_read <= 0;
o_bus_dp_write <= 0;
end
/*
* reading
* note: starts immediately
*/
if (setup_load_dp_read) begin
o_bus_load_dp <= 1;
o_bus_dp_read <= 1;
end
if (read_done) begin
o_bus_load_dp <= 0;
o_bus_dp_read <= 0;
end
/*
* writing
*/
// setup the order to load DP in time
if (setup_load_dp) begin
if (setup_load_dp_write) begin
o_bus_load_dp <= 1;
end

View file

@ -29,6 +29,7 @@ module saturn_bus_ctrl (
i_load_pc,
i_cmd_load_dp,
i_read_pc,
i_cmd_dp_read,
i_cmd_dp_write,
i_cmd_reset,
i_cmd_config,
@ -57,6 +58,7 @@ input wire [19:0] i_address;
input wire [0:0] i_load_pc;
input wire [0:0] i_cmd_load_dp;
input wire [0:0] i_read_pc;
input wire [0:0] i_cmd_dp_read;
input wire [0:0] i_cmd_dp_write;
input wire [0:0] i_cmd_reset;
input wire [0:0] i_cmd_config;
@ -84,6 +86,7 @@ wire [0:0] addr_s;
assign addr_s = addr_cnt == 5;
reg [0:0] cmd_pc_read_s;
reg [0:0] dp_read_s;
reg [0:0] cmd_dp_write_s;
reg [0:0] cmd_load_dp_s;
reg [0:0] cmd_config_s;
@ -93,6 +96,12 @@ wire [0:0] do_cmd_pc_read;
wire [0:0] do_display_stalled;
wire [0:0] do_cmd_load_dp;
wire [0:0] do_dp_read_data;
wire [0:0] do_dp_read_data_sc;
wire [0:0] do_dp_read_data_uc;
wire [0:0] do_pc_read_after_dp_read;
wire [0:0] do_cleanup_after_dp_read;
wire [0:0] do_cmd_dp_write;
wire [0:0] do_dp_write_data;
wire [0:0] do_pc_read_after_dp_write;
@ -109,8 +118,16 @@ wire [0:0] cmd_reset_sc;
wire [0:0] cmd_reset_uc;
wire [0:0] do_unstall;
wire [0:0] do_cleanup;
assign do_cmd_load_dp = i_cmd_load_dp && !cmd_load_dp_s;
assign do_dp_read_data = i_cmd_dp_read && cmd_load_dp_s && (addr_s || dp_read_s);
assign do_dp_read_data_sc = i_cmd_dp_read && cmd_load_dp_s && addr_s && !dp_read_s;
assign do_dp_read_data_uc = i_cmd_dp_read && cmd_load_dp_s && addr_s && dp_read_s;
assign do_pc_read_after_dp_read = i_read_stall && !i_cmd_dp_read && cmd_load_dp_s && !addr_s && dp_read_s;
assign do_cleanup_after_dp_read = !i_read_stall && !i_cmd_dp_read && cmd_load_dp_s && !addr_s && dp_read_s;
assign do_cmd_dp_write = i_cmd_dp_write && cmd_load_dp_s && addr_s && !cmd_dp_write_s;
assign do_dp_write_data = i_cmd_dp_write && cmd_load_dp_s && addr_s && cmd_dp_write_s;
assign do_pc_read_after_dp_write = !i_cmd_dp_write && cmd_load_dp_s && cmd_dp_write_s;
@ -127,17 +144,26 @@ assign cmd_reset_sc = !o_stalled_by_bus && i_cmd_reset && !cmd_rese
assign cmd_reset_uc = cmd_reset_s && cmd_pc_read_s;
assign do_cmd_pc_read = !cmd_pc_read_s &&
(do_pc_read_after_dp_write ||
(do_pc_read_after_dp_read ||
do_pc_read_after_dp_write ||
do_pc_read_after_config ||
do_pc_read_after_reset);
assign do_display_stalled = i_read_stall && !o_stalled_by_bus &&
!(do_cmd_pc_read ||
do_dp_read_data ||
do_pc_read_after_dp_read ||
do_cmd_dp_write ||
do_dp_write_data ||
do_pc_read_after_dp_write);
assign do_unstall = cmd_load_dp_dp_write_uc ||
assign do_unstall = do_dp_read_data_uc ||
cmd_load_dp_dp_write_uc ||
cmd_config_uc ||
cmd_reset_uc;
assign do_cleanup = do_cleanup_after_dp_read ||
cmd_load_dp_dp_write_uc ||
cmd_config_uc ||
cmd_reset_uc;
/*
@ -146,7 +172,7 @@ assign do_unstall = cmd_load_dp_dp_write_uc ||
`ifdef SIM
`define ROMBITS 20
`else
`define ROMBITS 10
`define ROMBITS 16
`endif
reg [3:0] rom [0:2**`ROMBITS-1];
@ -155,13 +181,11 @@ 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);
// $monitor("MONITOR : strb %b | o_bus_data %h | i_bus_data %h", o_bus_strobe, o_bus_data, i_bus_data);
// $monitor("MONITOR : i_cmd_dp_write %b | cmd_load_dp_s %b | addr_s %b | dp_write_reset %b",
// i_cmd_dp_write, cmd_load_dp_s, addr_s, cmd_load_dp_dp_write_uc);
// $monitor({"o_stalled_by_bus %b | i_read_stall %b | i_cmd_dp_read %b |",
// " cmd_load_dp_s %b | addr_s %b | dp_read_s %b |do_dp_read_data %b"},
// o_stalled_by_bus, i_read_stall, i_cmd_dp_read, cmd_load_dp_s,
// addr_s, dp_read_s, do_dp_read_data);
`endif
end
@ -171,10 +195,6 @@ reg [0:0] send_addr;
reg [19:0] local_pc;
reg [19:0] local_dp;
reg [0:0] reset_sent;
reg [0:0] config_sent;
reg [0:0] send_pc_read;
always @(posedge i_clk) begin
if (i_reset) begin
last_cmd <= 0;
@ -183,11 +203,9 @@ always @(posedge i_clk) begin
o_bus_cmd_data <= 1; // 1 is the default level
addr_cnt <= 0;
send_addr <= 0;
reset_sent <= 0;
config_sent <= 0;
send_pc_read <= 0;
cmd_pc_read_s <= 0;
dp_read_s <= 0;
cmd_dp_write_s <= 0;
cmd_load_dp_s <= 0;
cmd_config_s <= 0;
@ -205,8 +223,10 @@ always @(posedge i_clk) begin
* reset flags
*/
if (do_unstall) begin
if (do_cleanup) begin
// $display("--------------------------------------------- BUS STATES CLEANUP");
cmd_pc_read_s <= 0;
dp_read_s <= 0;
cmd_dp_write_s <= 0;
cmd_load_dp_s <= 0;
cmd_config_s <= 0;
@ -290,14 +310,17 @@ always @(posedge i_clk) begin
o_bus_strobe <= 1;
end
/*
* nothing to do for reading data
*/
/*
* writing data to the bus,
* send DP_WRITE first if necessary
*/
if (do_dp_write_data) begin
if (last_cmd != `BUSCMD_DP_WRITE) begin
end else begin
if (last_cmd == `BUSCMD_DP_WRITE) 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;
@ -315,13 +338,19 @@ always @(posedge i_clk) begin
if (en_bus_recv) begin
if (!i_read_stall)
if (!i_read_stall || do_dp_read_data)
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]]);
$display("BUS_RECV %0d: [%d] <= READ(PC) [%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
`BUSCMD_DP_READ: begin
$display("BUS_RECV %0d: [%d] <= READ(DP) [%5h] %h", `PH_BUS_RECV, i_cycle_ctr, local_dp, rom[local_dp[`ROMBITS-1:0]]);
o_nibble <= rom[local_dp[`ROMBITS-1:0]];
local_dp <= local_dp + 1;
dp_read_s <= 1;
end
endcase
if (do_display_stalled) begin
@ -343,14 +372,13 @@ always @(posedge i_clk) begin
// stalling and unstalling stuff
if (cmd_reset_sc)
o_stalled_by_bus <= 1;
if (cmd_config_sc) begin
if (do_dp_read_data_sc || cmd_reset_sc || cmd_config_sc) begin
// $display("-------------------------------------- STALL");
o_stalled_by_bus <= 1;
end
if (do_unstall) begin
// $display("-------------------------------------- NO - STALL");
o_stalled_by_bus <= 0;
addr_cnt <= 0;
end
@ -375,9 +403,13 @@ always @(posedge i_clk) begin
`BUSCMD_LOAD_DP: local_dp <= i_address;
endcase
send_addr <= 0;
o_stalled_by_bus <= 0;
if (!do_dp_read_data) begin
// $display("-------------------------------------- NO - STALL (auto-change mode)");
o_stalled_by_bus <= 0;
end
end
`BUSCMD_PC_READ: begin end
`BUSCMD_DP_READ: begin end
`BUSCMD_DP_WRITE: begin end
`BUSCMD_CONFIGURE: begin end
`BUSCMD_RESET: begin end

View file

@ -174,8 +174,10 @@ saturn_alu m_alu (
.o_bus_load_pc (bus_load_pc),
.o_bus_load_dp (bus_load_dp),
.o_bus_pc_read (bus_pc_read),
.o_bus_dp_read (bus_dp_read),
.o_bus_dp_write (bus_dp_write),
.o_bus_config (bus_config),
.i_bus_nibble_in (bus_nibble_in),
.o_bus_nibble_out (bus_nibble_out),
.i_push (push),
@ -214,10 +216,11 @@ saturn_alu m_alu (
// interconnections
wire [19:0] bus_address;
wire [0:0] bus_pc_read;
wire [0:0] bus_dp_read;
wire [0:0] bus_dp_write;
wire [0:0] bus_load_pc;
wire [0:0] bus_load_dp;
wire [0:0] bus_pc_read;
wire [0:0] bus_dp_write;
wire [0:0] bus_config;
wire [3:0] bus_nibble_in;
@ -257,6 +260,7 @@ saturn_bus_ctrl m_bus_ctrl (
.i_load_pc (bus_load_pc),
.i_cmd_load_dp (bus_load_dp),
.i_read_pc (bus_pc_read),
.i_cmd_dp_read (bus_dp_read),
.i_cmd_dp_write (bus_dp_write),
.i_cmd_reset (ins_reset),
.i_cmd_config (bus_config),
@ -267,6 +271,7 @@ saturn_bus_ctrl m_bus_ctrl (
reg [0:0] mem_ctrl_stall;
wire [0:0] bus_stalls_core;
// bus to external modules
reg [3:0] bus_data_in;
wire [3:0] bus_data_out;
wire [0:0] bus_strobe;
@ -358,7 +363,7 @@ always @(posedge clk) begin
clock_end <= 0;
cycle_ctr <= ~0;
max_cycle <= 405;
max_cycle <= 420;
mem_ctrl_stall <= 0;
`ifndef SIM
@ -377,14 +382,6 @@ wire dec_stalled;
wire alu_stalled;
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 = ck_bus_recv && !dec_stalled;
wire dec_stalled_no_read;
assign dec_stalled_no_read = ck_bus_recv && !bus_stalls_core && dec_stalled;
wire bus_is_stalled;
assign bus_is_stalled = ck_bus_recv && bus_stalls_core;
assign halt = clock_end || inv_opcode;

View file

@ -515,6 +515,10 @@ always @(posedge i_clk) begin
o_alu_op <= `ALU_OP_COPY;
go_fields_table <= use_fields_tbl;
use_fields_tbl <= 0;
// do not block when we're reading
o_alu_no_stall <= !use_fields_tbl && i_nibble[1];
// o_alu_debug <= i_nibble[1];
block_15xx <= use_fields_tbl;
@ -528,10 +532,11 @@ always @(posedge i_clk) begin
`ifdef SIM
$display("block_15xx %h", i_nibble);
`endif
o_ins_alu_op <= 1;
o_ins_decoded <= 1;
next_nibble <= 0;
block_15xx <= 0;
o_alu_no_stall <= i_nibble[1];
o_ins_alu_op <= 1;
o_ins_decoded <= 1;
next_nibble <= 0;
block_15xx <= 0;
end
if (do_block_pointer_arith_const) begin