diff --git a/saturn_alu.v b/saturn_alu.v
index bcd6dbe..50c5882 100644
--- a/saturn_alu.v
+++ b/saturn_alu.v
@@ -1,4 +1,22 @@
+/*
+ This file is part of hp_saturn.
+
+ hp_saturn is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ any later version.
+
+ hp_saturn is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Foobar. If not, see .
+
+ */
+
`ifndef _SATURN_ALU
`define _SATURN_ALU
@@ -26,6 +44,7 @@ module saturn_alu (
i_stalled,
o_bus_address,
+ o_bus_xfr_cnt,
o_bus_pc_read,
o_bus_dp_read,
o_bus_dp_write,
@@ -57,6 +76,8 @@ module saturn_alu (
i_ins_set_mode,
i_ins_rtn,
i_ins_config,
+ i_ins_mem_xfr,
+ i_xfr_dir_out,
i_ins_unconfig,
i_mode_dec,
@@ -81,6 +102,7 @@ input wire [0:0] i_en_alu_save;
input wire [0:0] i_stalled;
output reg [19:0] o_bus_address;
+output reg [3:0] o_bus_xfr_cnt;
output reg [0:0] o_bus_pc_read;
output reg [0:0] o_bus_dp_read;
output reg [0:0] o_bus_dp_write;
@@ -121,6 +143,8 @@ input wire [0:0] i_ins_test_go;
input wire [0:0] i_ins_set_mode;
input wire [0:0] i_ins_rtn;
input wire [0:0] i_ins_config;
+input wire [0:0] i_ins_mem_xfr;
+input wire [0:0] i_xfr_dir_out;
input wire [0:0] i_ins_unconfig;
input wire [0:0] i_mode_dec;
@@ -278,7 +302,7 @@ wire bus_commands;
assign bus_commands = o_bus_config || o_bus_dp_write ;
assign o_alu_stall_dec = alu_initializing ||
- (alu_run && (!i_alu_no_stall || alu_finish)) ||
+ (alu_run && (!i_alu_no_stall || alu_finish || i_ins_mem_xfr)) ||
i_stalled || bus_commands;
@@ -900,19 +924,24 @@ reg [0:0] write_done;
reg [1:0] extra_cycles;
wire [0:0] read_done;
+wire [0:0] read_done_t;
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 read_done = is_mem_read && do_alu_save && ((f_cur +1) == f_last);
+assign read_done_t = is_mem_read && do_alu_save && ((f_cur +1) == f_last);
+assign read_done = (phase == 3) && i_stalled && is_mem_read && !do_alu_save && (f_cur == 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;
+ reg [3:0] _f;
+ reg [3:0] _l;
+
always @(posedge i_clk) begin
// reset stuff
@@ -933,9 +962,19 @@ always @(posedge i_clk) begin
if (setup_load_dp_read) begin
o_bus_load_dp <= 1;
o_bus_dp_read <= 1;
+ $display("%0d =========================================== XFR INIT %0d %0d => %0d",
+ phase, f_first, f_last, f_last - f_first);
+ o_bus_xfr_cnt <= f_last - f_first;
+ end
+
+ // $display("phase %0d | i_stalled %b | is_mem_read %b | do_alu_save %b | f_cur+1 %0d | f_last %0d | read_done %b",
+ // phase, i_stalled, is_mem_read, do_alu_save, f_cur+1, f_last, read_done);
+ if (read_done_t) begin
+ $display("============================================= NEW read done");
end
if (read_done) begin
+ $display("============================================= old read_done");
o_bus_load_dp <= 0;
o_bus_dp_read <= 0;
end
diff --git a/saturn_core.v b/saturn_core.v
index a8f9b5b..b4db99d 100644
--- a/saturn_core.v
+++ b/saturn_core.v
@@ -1,5 +1,21 @@
/*
- * Licence: GPLv3 or later
+ (c) Raphaƫl Jacquot 2019
+
+ This file is part of hp_saturn.
+
+ hp_saturn is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ any later version.
+
+ hp_saturn is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Foobar. If not, see .
+
*/
`default_nettype none //
@@ -117,9 +133,9 @@ saturn_decoder m_decoder (
.i_en_dbg (ck_debugger),
.i_en_dec (ck_inst_dec),
.i_pc (reg_pc),
- .i_bus_load_pc (bus_load_pc),
+ .i_bus_load_pc (alu_bus_load_pc),
.i_stalled (dec_stalled),
- .i_nibble (bus_nibble_in),
+ .i_nibble (ctrl_bus_nibble_in),
.i_reg_p (reg_p),
@@ -154,7 +170,9 @@ saturn_decoder m_decoder (
.o_ins_alu_op (ins_alu_op),
.o_ins_test_go (ins_test_go),
.o_ins_reset (ins_reset),
- .o_ins_config (ins_config)
+ .o_ins_config (ins_config),
+ .o_ins_mem_xfr (ins_mem_xfr),
+ .o_xfr_dir_out (xfr_dir_out)
);
wire [0:0] inc_pc;
@@ -189,6 +207,8 @@ wire [0:0] ins_alu_op;
wire [0:0] ins_test_go;
wire [0:0] ins_reset;
wire [0:0] ins_config;
+wire [0:0] ins_mem_xfr;
+wire [0:0] xfr_dir_out;
wire [0:0] ins_unconfig;
@@ -204,15 +224,16 @@ saturn_alu m_alu (
.i_en_alu_save (ck_alu_save),
.i_stalled (alu_stalled),
- .o_bus_address (bus_address),
- .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),
+ .o_bus_address (alu_bus_address),
+ .o_bus_xfr_cnt (alu_bus_xfr_cnt),
+ .o_bus_load_pc (alu_bus_load_pc),
+ .o_bus_load_dp (alu_bus_load_dp),
+ .o_bus_pc_read (alu_bus_pc_read),
+ .o_bus_dp_read (alu_bus_dp_read),
+ .o_bus_dp_write (alu_bus_dp_write),
+ .o_bus_config (alu_bus_config),
+ .i_bus_nibble_in (ctrl_bus_nibble_in),
+ .o_bus_nibble_out (alu_bus_nibble_out),
.i_push (push),
.i_pop (pop),
@@ -236,6 +257,8 @@ saturn_alu m_alu (
.i_ins_set_mode (ins_set_mode),
.i_ins_rtn (ins_rtn),
.i_ins_config (ins_config),
+ .i_ins_mem_xfr (ins_mem_xfr),
+ .i_xfr_dir_out (xfr_dir_out),
.i_ins_unconfig (ins_unconfig),
.i_mode_dec (mode_dec),
@@ -250,16 +273,17 @@ 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_config;
+wire [19:0] alu_bus_address;
+wire [3:0] alu_bus_xfr_cnt;
+wire [0:0] alu_bus_pc_read;
+wire [0:0] alu_bus_dp_read;
+wire [0:0] alu_bus_dp_write;
+wire [0:0] alu_bus_load_pc;
+wire [0:0] alu_bus_load_dp;
+wire [0:0] alu_bus_config;
-wire [3:0] bus_nibble_in;
-wire [3:0] bus_nibble_out;
+wire [3:0] ctrl_bus_nibble_in;
+wire [3:0] alu_bus_nibble_out;
wire [0:0] alu_stalls_dec;
wire [3:0] reg_p;
@@ -277,11 +301,8 @@ saturn_bus_ctrl m_bus_ctrl (
.i_reset (i_reset),
.i_phase (o_phase),
.i_cycle_ctr (cycle_ctr),
- .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),
+ .i_alu_busy (dec_stalled),
.o_stall_alu (bus_stalls_core),
//bus i/o
@@ -293,16 +314,19 @@ saturn_bus_ctrl m_bus_ctrl (
// interface to the rest of the machine
.i_alu_pc (reg_pc),
- .i_address (bus_address),
- .i_cmd_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_address (alu_bus_address),
+ .i_cmd_load_pc (alu_bus_load_pc),
+ .i_cmd_load_dp (alu_bus_load_dp),
+ .i_read_pc (alu_bus_pc_read),
+ .i_cmd_dp_read (alu_bus_dp_read),
+ .i_cmd_dp_write (alu_bus_dp_write),
.i_cmd_reset (ins_reset),
- .i_cmd_config (bus_config),
- .i_nibble (bus_nibble_out),
- .o_nibble (bus_nibble_in)
+ .i_cmd_config (alu_bus_config),
+ .i_mem_xfr (ins_mem_xfr),
+ .i_xfr_out (xfr_dir_out),
+ .i_xfr_cnt (alu_bus_xfr_cnt),
+ .i_nibble (alu_bus_nibble_out),
+ .o_nibble (ctrl_bus_nibble_in)
);
reg [0:0] mem_ctrl_stall;
@@ -394,7 +418,7 @@ always @(posedge i_clk) begin
clock_end <= 0;
cycle_ctr <= ~0;
- max_cycle <= 278;
+ max_cycle <= 72;
mem_ctrl_stall <= 0;
`ifndef SIM
@@ -469,10 +493,12 @@ reg [2:0] addr_c;
wire [0:0] s_load_pc;
wire [0:0] s_load_dp;
wire [0:0] s_pc_read;
+wire [0:0] s_dp_read;
wire [0:0] s_dp_write;
assign s_load_pc = (last_bus_cmd == `BUSCMD_LOAD_PC);
assign s_load_dp = (last_bus_cmd == `BUSCMD_LOAD_DP);
assign s_pc_read = (last_bus_cmd == `BUSCMD_PC_READ);
+assign s_dp_read = (last_bus_cmd == `BUSCMD_DP_READ);
assign s_dp_write = (last_bus_cmd == `BUSCMD_DP_WRITE);
initial begin
@@ -538,6 +564,12 @@ always @(posedge i_bus_strobe) begin
local_pc <= local_pc + 1;
end
+ if (i_bus_cmd_data && s_dp_read) begin
+ o_bus_data_out <= rom[local_dp];
+ $display("ROM %0d: [%d] %h <= DP_READ [%5h]", i_phase, cycles, rom[local_dp], local_dp);
+ local_dp <= local_dp + 1;
+ end
+
if (i_bus_cmd_data && s_dp_write) begin
$display("ROM %0d: [%d] %h => DP_WRITE [%5h] (ignored)", i_phase, cycles, i_bus_data_in, local_dp);
end