mirror of
https://github.com/sxpert/hp-saturn
synced 2024-11-16 19:50:19 +01:00
implement read from DP
This commit is contained in:
parent
0a45b014d7
commit
1444baca19
5 changed files with 114 additions and 57 deletions
|
@ -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
|
||||
|
|
54
saturn_alu.v
54
saturn_alu.v
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue