2019-02-20 09:20:16 +01:00
|
|
|
/*
|
|
|
|
(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 <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2019-02-16 22:38:44 +01:00
|
|
|
`ifndef _SATURN_BUS_CTRL
|
|
|
|
`define _SATURN_BUS_CTRL
|
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
`default_nettype none
|
|
|
|
|
2019-02-16 22:38:44 +01:00
|
|
|
`include "def-clocks.v"
|
|
|
|
`include "def-buscmd.v"
|
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
/*
|
|
|
|
* enable more debug messages
|
|
|
|
*/
|
|
|
|
`ifdef SIM
|
|
|
|
`define DEBUG_CTRL
|
|
|
|
`endif
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-02-16 22:38:44 +01:00
|
|
|
module saturn_bus_ctrl (
|
|
|
|
i_clk,
|
|
|
|
i_reset,
|
2019-02-19 16:17:35 +01:00
|
|
|
i_phase,
|
2019-02-16 22:38:44 +01:00
|
|
|
i_cycle_ctr,
|
|
|
|
i_stalled,
|
2019-02-20 09:20:16 +01:00
|
|
|
i_alu_busy,
|
2019-02-16 22:38:44 +01:00
|
|
|
|
2019-02-19 16:17:35 +01:00
|
|
|
o_stall_alu,
|
2019-02-16 22:38:44 +01:00
|
|
|
|
|
|
|
// bus i/o
|
2019-02-19 16:17:35 +01:00
|
|
|
o_bus_reset,
|
2019-02-16 22:38:44 +01:00
|
|
|
i_bus_data,
|
|
|
|
o_bus_data,
|
|
|
|
o_bus_strobe,
|
|
|
|
o_bus_cmd_data,
|
|
|
|
|
|
|
|
// interface to the rest of the machine
|
|
|
|
i_alu_pc,
|
|
|
|
i_address,
|
2019-02-19 16:17:35 +01:00
|
|
|
i_cmd_load_pc,
|
2019-02-17 20:23:43 +01:00
|
|
|
i_cmd_load_dp,
|
2019-02-17 12:05:38 +01:00
|
|
|
i_read_pc,
|
2019-02-18 07:43:36 +01:00
|
|
|
i_cmd_dp_read,
|
2019-02-17 20:23:43 +01:00
|
|
|
i_cmd_dp_write,
|
2019-02-17 15:03:36 +01:00
|
|
|
i_cmd_reset,
|
2019-02-17 19:29:39 +01:00
|
|
|
i_cmd_config,
|
2019-02-20 09:20:16 +01:00
|
|
|
i_mem_xfr,
|
|
|
|
i_xfr_out,
|
|
|
|
i_xfr_cnt,
|
2019-02-16 22:38:44 +01:00
|
|
|
i_nibble,
|
|
|
|
o_nibble
|
|
|
|
);
|
|
|
|
|
|
|
|
input wire [0:0] i_clk;
|
|
|
|
input wire [0:0] i_reset;
|
2019-02-19 16:17:35 +01:00
|
|
|
input wire [1:0] i_phase;
|
2019-02-16 22:38:44 +01:00
|
|
|
input wire [31:0] i_cycle_ctr;
|
|
|
|
input wire [0:0] i_stalled;
|
2019-02-20 09:20:16 +01:00
|
|
|
input wire [0:0] i_alu_busy;
|
2019-02-17 08:35:26 +01:00
|
|
|
|
2019-02-19 16:17:35 +01:00
|
|
|
output reg [0:0] o_stall_alu;
|
2019-02-16 22:38:44 +01:00
|
|
|
|
2019-02-19 16:17:35 +01:00
|
|
|
output reg [0:0] o_bus_reset;
|
2019-02-16 22:38:44 +01:00
|
|
|
input wire [3:0] i_bus_data;
|
|
|
|
output reg [3:0] o_bus_data;
|
2019-02-19 16:17:35 +01:00
|
|
|
output wire [0:0] o_bus_strobe;
|
2019-02-16 22:38:44 +01:00
|
|
|
output reg [0:0] o_bus_cmd_data;
|
|
|
|
|
|
|
|
input wire [19:0] i_alu_pc;
|
|
|
|
input wire [19:0] i_address;
|
2019-02-19 16:17:35 +01:00
|
|
|
input wire [0:0] i_cmd_load_pc;
|
2019-02-17 20:23:43 +01:00
|
|
|
input wire [0:0] i_cmd_load_dp;
|
2019-02-17 12:05:38 +01:00
|
|
|
input wire [0:0] i_read_pc;
|
2019-02-18 07:43:36 +01:00
|
|
|
input wire [0:0] i_cmd_dp_read;
|
2019-02-17 20:23:43 +01:00
|
|
|
input wire [0:0] i_cmd_dp_write;
|
2019-02-17 15:03:36 +01:00
|
|
|
input wire [0:0] i_cmd_reset;
|
2019-02-17 19:29:39 +01:00
|
|
|
input wire [0:0] i_cmd_config;
|
2019-02-20 09:20:16 +01:00
|
|
|
input wire [0:0] i_mem_xfr;
|
|
|
|
input wire [0:0] i_xfr_out;
|
|
|
|
input wire [3:0] i_xfr_cnt;
|
2019-02-17 19:29:39 +01:00
|
|
|
|
2019-02-16 22:38:44 +01:00
|
|
|
input wire [3:0] i_nibble;
|
|
|
|
output reg [3:0] o_nibble;
|
|
|
|
|
2019-02-18 11:36:28 +01:00
|
|
|
/******************************************************************************
|
|
|
|
*
|
|
|
|
* clocking enables
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
2019-02-19 16:17:35 +01:00
|
|
|
// bus startup
|
|
|
|
reg [0:0] bus_out_of_reset;
|
|
|
|
wire [0:0] bus_reset_event;
|
|
|
|
wire [0:0] reset_bus;
|
|
|
|
wire [0:0] bus_start;
|
|
|
|
wire [0:0] bus_active;
|
|
|
|
reg [0:0] strobe_on;
|
|
|
|
assign bus_reset_event = !i_reset && !i_stalled && bus_out_of_reset;
|
|
|
|
assign reset_bus = bus_reset_event && (i_phase == 0) && !strobe_on;
|
|
|
|
assign bus_start = bus_reset_event && (i_phase == 1) && strobe_on;
|
|
|
|
assign bus_active = !i_reset && !i_stalled && !bus_out_of_reset;
|
|
|
|
assign o_bus_strobe = (i_phase == 1) && strobe_on;
|
|
|
|
|
|
|
|
// events phases
|
|
|
|
|
|
|
|
wire [0:0] phase_0;
|
|
|
|
wire [0:0] phase_1;
|
|
|
|
wire [0:0] phase_2;
|
|
|
|
wire [0:0] phase_3;
|
|
|
|
|
|
|
|
assign phase_0 = bus_active && (i_phase == 0);
|
|
|
|
assign phase_1 = bus_active && (i_phase == 1);
|
|
|
|
assign phase_2 = bus_active && (i_phase == 2);
|
|
|
|
assign phase_3 = bus_active && (i_phase == 3);
|
2019-02-16 22:38:44 +01:00
|
|
|
|
2019-02-18 11:36:28 +01:00
|
|
|
/******************************************************************************
|
|
|
|
*
|
2019-02-20 09:20:16 +01:00
|
|
|
* THE EVIL STATE MACHINE !
|
2019-02-18 11:36:28 +01:00
|
|
|
*
|
2019-02-20 09:20:16 +01:00
|
|
|
*****************************************************************************/
|
2019-02-18 17:38:25 +01:00
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
// actual commands
|
2019-02-19 16:17:35 +01:00
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
/* the last command sent to the bus
|
|
|
|
* initialized to 0, BUSCMD_NOP
|
|
|
|
*/
|
|
|
|
reg [3:0] last_cmd;
|
|
|
|
|
|
|
|
/* tests on last_cmd */
|
|
|
|
|
|
|
|
wire [0:0] LC_pc_read;
|
|
|
|
wire [0:0] LC_pc_write;
|
|
|
|
wire [0:0] LC_dp_read;
|
|
|
|
wire [0:0] LC_dp_write;
|
|
|
|
wire [0:0] LC_load_pc;
|
|
|
|
wire [0:0] LC_load_dp;
|
|
|
|
|
|
|
|
assign LC_pc_read = (last_cmd == `BUSCMD_PC_READ);
|
|
|
|
assign LC_pc_write = (last_cmd == `BUSCMD_PC_WRITE);
|
|
|
|
assign LC_dp_read = (last_cmd == `BUSCMD_DP_READ);
|
|
|
|
assign LC_dp_write = (last_cmd == `BUSCMD_DP_WRITE);
|
|
|
|
assign LC_load_pc = (last_cmd == `BUSCMD_LOAD_PC);
|
|
|
|
assign LC_load_dp = (last_cmd == `BUSCMD_LOAD_DP);
|
|
|
|
|
|
|
|
/* current pointer
|
|
|
|
* 0: PC
|
|
|
|
* 1: DP
|
|
|
|
*/
|
|
|
|
reg [0:0] current_pointer;
|
2019-02-18 17:38:25 +01:00
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
/*
|
|
|
|
* Events naming conventions
|
2019-02-19 16:17:35 +01:00
|
|
|
*
|
2019-02-20 09:20:16 +01:00
|
|
|
* bus commands (use the "cmd" prefix) :
|
2019-02-19 16:17:35 +01:00
|
|
|
*
|
2019-02-20 09:20:16 +01:00
|
|
|
* cmd_[foo]_F : flag to indicate cmd_[foo] was done
|
|
|
|
* cmd_[foo]_TST : test if cmd_[foo] needs to be done
|
|
|
|
* cmd_[foo]_x : whatever needs to be done for cmd_[foo], step x
|
|
|
|
* cmd_[foo]_STR : when there is a need for a strobe on phase 0
|
|
|
|
* cmd_[foo]_STx : if cmd_[foo] needs to stall the ALU and core, step x
|
|
|
|
* cmd_[foo]_USx : if cmd_[foo] neesd to un-stall the ALU and core, step x
|
|
|
|
* cmd_[foo]_C : when flags for the execution of cmd_[foo] need to be cleaned
|
|
|
|
*
|
|
|
|
* bus actions (use the "do" prefix) :
|
|
|
|
*
|
|
|
|
* do_[foo]_TST : test if do_[foo] can be done
|
|
|
|
* do_[foo]_x : whatever needs to be done for do_[foo], step x
|
|
|
|
* do_[foo]_STR : when there is a need for a strobe on phase 0
|
|
|
|
*
|
|
|
|
* note: strobe removal is automatic on phase 1
|
|
|
|
*
|
|
|
|
*/
|
2019-02-17 19:29:39 +01:00
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
/*
|
|
|
|
* read from the PC pointer
|
|
|
|
*/
|
|
|
|
|
|
|
|
// sending readpc
|
|
|
|
reg [0:0] cmd_PC_READ_F;
|
2019-02-20 16:21:39 +01:00
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
wire [0:0] cmd_PC_READ_TST;
|
|
|
|
wire [0:0] cmd_PC_READ_0;
|
|
|
|
wire [0:0] cmd_PC_READ_STR;
|
|
|
|
|
|
|
|
assign cmd_PC_READ_TST = !cmd_PC_READ_F &&
|
2019-02-20 16:21:39 +01:00
|
|
|
(cmd_DP_WRITE_F1 || cmd_CONFIGURE_F1 || cmd_RESET_F);
|
|
|
|
assign cmd_PC_READ_0 = phase_0 && cmd_PC_READ_TST; // sets cmd_PC_READ_F
|
|
|
|
assign cmd_PC_READ_STR = cmd_PC_READ_0;
|
2019-02-20 09:20:16 +01:00
|
|
|
|
|
|
|
// doing actual reads
|
|
|
|
wire [0:0] do_READ_PC_TST;
|
|
|
|
wire [0:0] do_READ_PC_0;
|
|
|
|
wire [0:0] do_READ_PC_STR;
|
|
|
|
|
|
|
|
assign do_READ_PC_TST = !i_alu_busy && LC_pc_read;
|
|
|
|
assign do_READ_PC_0 = phase_1 && do_READ_PC_TST;
|
|
|
|
assign do_READ_PC_STR = do_READ_PC_TST;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* read from the DP pointer
|
|
|
|
*/
|
|
|
|
|
2019-02-20 16:21:39 +01:00
|
|
|
reg [0:0] cmd_DP_READ_F;
|
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
|
|
|
|
wire [0:0] do_read_dp_en;
|
|
|
|
wire [0:0] do_read_dp_str;
|
|
|
|
reg [0:0] do_read_dp_s;
|
|
|
|
wire [0:0] do_read_dp;
|
|
|
|
wire [0:0] do_read_dp_US;
|
|
|
|
wire [0:0] do_read_dp_C;
|
|
|
|
wire [0:0] do_read_dp_US2;
|
|
|
|
assign do_read_dp_en = i_cmd_dp_read && LC_dp_read;
|
|
|
|
assign do_read_dp_str = phase_0 && do_read_dp_en;
|
|
|
|
assign do_read_dp = phase_1 && do_read_dp_en;
|
|
|
|
assign do_read_dp_US = phase_3 && do_read_dp_en && o_stall_alu;
|
|
|
|
assign do_read_dp_C = phase_0 && !i_cmd_dp_read && LC_dp_read && do_read_dp_s;
|
|
|
|
assign do_read_dp_US2 = phase_3 && do_read_dp_s && cmd_PC_READ_F;
|
2019-02-19 16:17:35 +01:00
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
/*
|
|
|
|
* write to the DP pointer
|
|
|
|
*/
|
|
|
|
|
|
|
|
// setup the DP pointer
|
2019-02-20 16:21:39 +01:00
|
|
|
reg [0:0] cmd_DP_WRITE_F0;
|
|
|
|
reg [0:0] cmd_DP_WRITE_F1;
|
|
|
|
wire [0:0] cmd_DP_WRITE_TST;
|
|
|
|
wire [0:0] cmd_DP_WRITE_0;
|
|
|
|
wire [0:0] cmd_DP_WRITE_1;
|
|
|
|
wire [0:0] cmd_DP_WRITE_STR;
|
|
|
|
wire [0:0] cmd_DP_WRITE_US0;
|
|
|
|
wire [0:0] cmd_DP_WRITE_US1;
|
|
|
|
wire [0:0] cmd_DP_WRITE_C;
|
|
|
|
assign cmd_DP_WRITE_TST = i_cmd_dp_write && LC_dp_read && !cmd_DP_WRITE_F0;
|
|
|
|
assign cmd_DP_WRITE_0 = phase_0 && cmd_DP_WRITE_TST; // sets cmd_DP_WRITE_F0
|
|
|
|
assign cmd_DP_WRITE_STR = cmd_DP_WRITE_0;
|
|
|
|
assign cmd_DP_WRITE_US0 = phase_2 && cmd_DP_WRITE_F0 && !cmd_DP_WRITE_F1 && o_stall_alu;
|
|
|
|
// after all nibbles were sent
|
|
|
|
assign cmd_DP_WRITE_1 = phase_3 && !i_cmd_dp_write && cmd_DP_WRITE_F0 && !cmd_DP_WRITE_F1; // sets cmd_DP_WRITE_F1
|
|
|
|
assign cmd_DP_WRITE_US1 = phase_2 && cmd_DP_WRITE_F1;
|
|
|
|
assign cmd_DP_WRITE_C = phase_3 && cmd_DP_WRITE_F1;
|
2019-02-20 09:20:16 +01:00
|
|
|
|
|
|
|
// do actual writes
|
2019-02-20 16:21:39 +01:00
|
|
|
wire [0:0] do_WRITE_DP_TST;
|
|
|
|
wire [0:0] do_WRITE_DP_0;
|
|
|
|
wire [0:0] do_WRITE_DP_STR;
|
|
|
|
assign do_WRITE_DP_TST = !o_stall_alu && i_cmd_dp_write && LC_dp_write;
|
|
|
|
assign do_WRITE_DP_STR = phase_0 && do_WRITE_DP_TST;
|
|
|
|
assign do_WRITE_DP_0 = phase_0 && do_WRITE_DP_TST;
|
2019-02-17 19:29:39 +01:00
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
/*
|
2019-02-20 16:21:39 +01:00
|
|
|
* LOAD_PC : load a new PC in
|
2019-02-20 09:20:16 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
reg [0:0] cmd_LOAD_PC_F;
|
2019-02-20 16:21:39 +01:00
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
wire [0:0] cmd_LOAD_PC_TST;
|
|
|
|
wire [0:0] cmd_LOAD_PC_0;
|
|
|
|
wire [0:0] cmd_LOAD_PC_STR;
|
|
|
|
wire [0:0] cmd_LOAD_PC_C;
|
2019-02-20 16:21:39 +01:00
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
assign cmd_LOAD_PC_TST = i_cmd_load_pc;
|
2019-02-20 16:21:39 +01:00
|
|
|
assign cmd_LOAD_PC_0 = phase_0 && cmd_LOAD_PC_TST; // sets cmd_LOAD_PC_F
|
2019-02-20 09:20:16 +01:00
|
|
|
assign cmd_LOAD_PC_STR = cmd_LOAD_PC_TST;
|
|
|
|
assign cmd_LOAD_PC_C = phase_3 && do_auto_PC_READ_TST;
|
|
|
|
|
2019-02-20 16:21:39 +01:00
|
|
|
/*
|
|
|
|
* auto switch to PC_READ after LOAD_PC
|
|
|
|
*/
|
2019-02-20 09:20:16 +01:00
|
|
|
wire [0:0] do_auto_PC_READ_TST;
|
|
|
|
wire [0:0] do_auto_PC_READ_0;
|
|
|
|
wire [0:0] do_auto_PC_READ_US0;
|
2019-02-20 16:21:39 +01:00
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
assign do_auto_PC_READ_TST = cmd_LOAD_PC_F && addr_loop_done;
|
|
|
|
assign do_auto_PC_READ_0 = phase_1 && do_auto_PC_READ_TST;
|
|
|
|
assign do_auto_PC_READ_US0 = phase_3 && o_stall_alu && do_auto_PC_READ_TST && cmd_LOAD_PC_F;
|
|
|
|
|
|
|
|
/*
|
2019-02-20 16:21:39 +01:00
|
|
|
* LOAD_DP : load a new DP in
|
2019-02-20 09:20:16 +01:00
|
|
|
*/
|
2019-02-17 19:29:39 +01:00
|
|
|
|
2019-02-20 16:21:39 +01:00
|
|
|
reg [0:0] cmd_LOAD_DP_F;
|
2019-02-19 16:17:35 +01:00
|
|
|
|
2019-02-20 16:21:39 +01:00
|
|
|
wire [0:0] cmd_LOAD_DP_TST;
|
|
|
|
wire [0:0] cmd_LOAD_DP_0;
|
|
|
|
wire [0:0] cmd_LOAD_DP_STR;
|
|
|
|
wire [0:0] cmd_LOAD_DP_C;
|
|
|
|
|
|
|
|
assign cmd_LOAD_DP_TST = i_cmd_load_dp;
|
|
|
|
assign cmd_LOAD_DP_0 = phase_0 && cmd_LOAD_DP_TST; // sets cmd_LOAD_DP_F
|
|
|
|
assign cmd_LOAD_DP_STR = cmd_LOAD_DP_TST;
|
|
|
|
assign cmd_LOAD_DP_C = phase_3 && do_auto_DP_READ_TST;
|
2019-02-20 09:20:16 +01:00
|
|
|
|
|
|
|
/*
|
2019-02-20 16:21:39 +01:00
|
|
|
* auto switch to PC_READ after LOAD_PC
|
2019-02-20 09:20:16 +01:00
|
|
|
*/
|
2019-02-20 16:21:39 +01:00
|
|
|
wire [0:0] do_auto_DP_READ_TST;
|
|
|
|
wire [0:0] do_auto_DP_READ_0;
|
|
|
|
wire [0:0] do_auto_DP_READ_US0;
|
|
|
|
|
|
|
|
assign do_auto_DP_READ_TST = cmd_LOAD_DP_F && addr_loop_done && !cmd_DP_READ_F;
|
|
|
|
assign do_auto_DP_READ_0 = phase_1 && do_auto_DP_READ_TST;
|
|
|
|
// does nothing ?
|
|
|
|
assign do_auto_DP_READ_US0 = phase_3 && o_stall_alu && do_auto_DP_READ_TST && cmd_LOAD_DP_F && !(cmd_DP_WRITE_F0); // || cmd_DP_READ_F);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* CONFIGURE : execute a configure
|
|
|
|
*/
|
|
|
|
|
|
|
|
reg [0:0] cmd_CONFIGURE_F0;
|
|
|
|
reg [0:0] cmd_CONFIGURE_F1;
|
|
|
|
|
|
|
|
wire [0:0] cmd_CONFIGURE_TST;
|
|
|
|
wire [0:0] cmd_CONFIGURE_0;
|
|
|
|
wire [0:0] cmd_CONFIGURE_STR;
|
|
|
|
wire [0:0] cmd_CONFIGURE_1;
|
|
|
|
wire [0:0] cmd_CONFIGURE_US0;
|
|
|
|
wire [0:0] cmd_CONFIGURE_C;
|
2019-02-20 09:20:16 +01:00
|
|
|
|
2019-02-20 16:21:39 +01:00
|
|
|
assign cmd_CONFIGURE_TST = i_cmd_config && !cmd_CONFIGURE_F0;
|
|
|
|
assign cmd_CONFIGURE_0 = phase_0 && cmd_CONFIGURE_TST; // sets cmd_CONFIGURE_F0
|
|
|
|
assign cmd_CONFIGURE_STR = cmd_CONFIGURE_0;
|
|
|
|
assign cmd_CONFIGURE_1 = phase_3 && cmd_CONFIGURE_F0 && is_loop_finished;
|
|
|
|
assign cmd_CONFIGURE_US0 = phase_1 && cmd_CONFIGURE_F1 && cmd_PC_READ_F;
|
|
|
|
assign cmd_CONFIGURE_C = phase_3 && cmd_CONFIGURE_F1 && cmd_PC_READ_F;
|
2019-02-17 19:29:39 +01:00
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
/*
|
2019-02-20 16:21:39 +01:00
|
|
|
* RESETexecute a bus reset
|
2019-02-20 09:20:16 +01:00
|
|
|
*/
|
2019-02-17 19:29:39 +01:00
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
reg [0:0] cmd_RESET_F;
|
2019-02-20 16:21:39 +01:00
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
wire [0:0] cmd_RESET_0;
|
2019-02-20 16:21:39 +01:00
|
|
|
wire [0:0] cmd_RESET_STR;
|
|
|
|
wire [0:0] cmd_RESET_ST0;
|
2019-02-20 09:20:16 +01:00
|
|
|
wire [0:0] cmd_RESET_US0;
|
|
|
|
wire [0:0] cmd_RESET_C;
|
2019-02-20 16:21:39 +01:00
|
|
|
|
|
|
|
assign cmd_RESET_0 = phase_0 && i_cmd_reset && !cmd_RESET_F && !cmd_PC_READ_F; // sets cmd_RESET_F
|
|
|
|
assign cmd_RESET_STR = cmd_RESET_0;
|
2019-02-20 09:20:16 +01:00
|
|
|
assign cmd_RESET_ST0 = phase_3 && i_cmd_reset && !cmd_RESET_F && !cmd_PC_READ_F;
|
|
|
|
assign cmd_RESET_US0 = phase_3 && i_cmd_reset && cmd_RESET_F && cmd_PC_READ_F;
|
|
|
|
assign cmd_RESET_C = phase_0 && i_cmd_reset && cmd_RESET_F && cmd_PC_READ_F;
|
2019-02-18 07:43:36 +01:00
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
// automatic stuff
|
2019-02-18 11:36:28 +01:00
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
wire [0:0] do_read;
|
|
|
|
assign do_read = do_READ_PC_0 || do_read_dp;
|
2019-02-16 22:38:44 +01:00
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
/*
|
|
|
|
* bus strobe management
|
|
|
|
*/
|
|
|
|
wire [0:0] do_cmd_strobe;
|
|
|
|
wire [0:0] do_read_strobe;
|
2019-02-20 16:21:39 +01:00
|
|
|
wire [0:0] do_write_strobe;
|
2019-02-19 16:17:35 +01:00
|
|
|
wire [0:0] do_strobe;
|
2019-02-20 09:20:16 +01:00
|
|
|
wire [0:0] do_remove_strobe;
|
2019-02-20 16:21:39 +01:00
|
|
|
assign do_cmd_strobe = cmd_PC_READ_STR || cmd_DP_WRITE_STR || cmd_LOAD_PC_STR || cmd_LOAD_DP_STR || cmd_CONFIGURE_STR || cmd_RESET_STR;
|
|
|
|
assign do_read_strobe = do_READ_PC_STR; // || do_READ_DP_STR;
|
|
|
|
assign do_write_strobe = do_WRITE_DP_STR;
|
2019-02-20 09:20:16 +01:00
|
|
|
assign do_strobe = phase_0 &&
|
2019-02-20 16:21:39 +01:00
|
|
|
(do_cmd_strobe || do_run_addr_loop || do_read_strobe || do_write_strobe);
|
2019-02-20 09:20:16 +01:00
|
|
|
assign do_remove_strobe = phase_1 && strobe_on;
|
2019-02-16 22:38:44 +01:00
|
|
|
|
2019-02-19 16:17:35 +01:00
|
|
|
wire [0:0] do_read_stalled_by_alu;
|
2019-02-20 09:20:16 +01:00
|
|
|
assign do_read_stalled_by_alu = phase_1 && i_alu_busy && LC_pc_read;
|
2019-02-18 11:36:28 +01:00
|
|
|
|
2019-02-19 16:17:35 +01:00
|
|
|
wire [0:0] do_unstall;
|
|
|
|
assign do_unstall = o_stall_alu &&
|
2019-02-20 09:20:16 +01:00
|
|
|
(do_read_dp_US2 ||
|
2019-02-20 16:21:39 +01:00
|
|
|
cmd_DP_WRITE_1 ||
|
|
|
|
cmd_DP_WRITE_US0 ||
|
|
|
|
cmd_DP_WRITE_US1 ||
|
2019-02-20 09:20:16 +01:00
|
|
|
do_auto_PC_READ_US0 ||
|
2019-02-20 16:21:39 +01:00
|
|
|
cmd_CONFIGURE_US0 ||
|
2019-02-20 09:20:16 +01:00
|
|
|
cmd_RESET_US0);
|
|
|
|
|
|
|
|
wire [0:0] do_load_clean;
|
2019-02-19 16:17:35 +01:00
|
|
|
wire [0:0] do_clean;
|
2019-02-20 09:20:16 +01:00
|
|
|
assign do_load_clean = cmd_LOAD_PC_C;
|
2019-02-20 16:21:39 +01:00
|
|
|
assign do_clean = do_read_dp_US2 || cmd_DP_WRITE_C || cmd_CONFIGURE_C || cmd_RESET_C;
|
2019-02-19 16:17:35 +01:00
|
|
|
|
|
|
|
reg [2:0] addr_loop_counter;
|
|
|
|
reg [0:0] addr_loop_done;
|
|
|
|
reg [0:0] init_addr_loop;
|
|
|
|
reg [0:0] run_addr_loop;
|
|
|
|
wire [0:0] do_init_addr_loop;
|
|
|
|
wire [0:0] do_run_addr_loop;
|
|
|
|
wire [0:0] will_loop_finish;
|
|
|
|
wire [0:0] is_loop_finished;
|
|
|
|
wire [0:0] do_reset_loop_counter;
|
|
|
|
assign do_init_addr_loop = phase_0 &&
|
|
|
|
(init_addr_loop ||
|
2019-02-20 09:20:16 +01:00
|
|
|
cmd_LOAD_PC_TST ||
|
2019-02-20 16:21:39 +01:00
|
|
|
cmd_LOAD_DP_TST ||
|
|
|
|
cmd_CONFIGURE_0);
|
2019-02-19 16:17:35 +01:00
|
|
|
assign do_run_addr_loop = phase_0 && run_addr_loop && !is_loop_finished;
|
|
|
|
assign will_loop_finish = addr_loop_counter == 4;
|
|
|
|
assign is_loop_finished = addr_loop_counter == 5;
|
|
|
|
assign do_reset_loop_counter = phase_3 && is_loop_finished;
|
|
|
|
|
2019-02-18 11:36:28 +01:00
|
|
|
/******************************************************************************
|
|
|
|
*
|
|
|
|
* the controller itself
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
2019-02-16 22:38:44 +01:00
|
|
|
initial begin
|
2019-02-17 12:05:38 +01:00
|
|
|
|
2019-02-18 11:36:28 +01:00
|
|
|
`ifdef SIM
|
2019-02-20 09:20:16 +01:00
|
|
|
|
|
|
|
/* debug load_pc
|
|
|
|
*/
|
|
|
|
// $monitor({"BUS - clk %b | ph %0d | osta %b | iabs %b | ",
|
|
|
|
// "LC_load_pc %b | addr_loop_done %b | do_auto_PC_READ_TST %b | cmd_LOAD_PC_F %b"},
|
|
|
|
// i_clk, i_phase, o_stall_alu, i_alu_busy,
|
|
|
|
// LC_load_pc, addr_loop_done, do_auto_PC_READ_TST, cmd_LOAD_PC_F);
|
|
|
|
|
2019-02-20 16:21:39 +01:00
|
|
|
/*
|
|
|
|
* debug auto_dp_read
|
|
|
|
*/
|
|
|
|
// $monitor({"BUS - clk %b | ph %0d | osta %b | iabs %b | ",
|
|
|
|
// "cmd_LOAD_DP_F %b | addr_loop_done %b | do_auto_DP_READ_TST %b"},
|
|
|
|
// i_clk, i_phase, o_stall_alu, i_alu_busy,
|
|
|
|
// cmd_LOAD_DP_F, addr_loop_done, do_auto_DP_READ_TST);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* debug dp_write
|
|
|
|
*/
|
|
|
|
$monitor({"BUS - clk %b | ph %0d | osta %b | iabs %b | ",
|
|
|
|
"i_cmd_dp_write %b | cmd_LOAD_DP_F %b | addr_loop_done %b | do_auto_DP_READ_TST %b | cmd_DP_WRITE_F0 %b | cnd_DP_WRITE_F1 %b"},
|
|
|
|
i_clk, i_phase, o_stall_alu, i_alu_busy,
|
|
|
|
i_cmd_dp_write, cmd_LOAD_DP_F, addr_loop_done, do_auto_DP_READ_TST, cmd_DP_WRITE_F0, cmd_DP_WRITE_F1);
|
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
|
|
|
|
/* debug strobe for reading
|
|
|
|
*/
|
|
|
|
// $monitor({"BUS - clk %b | ph %0d | osta %b | iabs %b | ",
|
|
|
|
// "cPR %b | cLP %b | dRP %b | dRD %b | dcs %b | dral %b | drs %b | stro %b | str %b"},
|
|
|
|
// i_clk, i_phase, o_stall_alu, i_alu_busy,
|
|
|
|
// cmd_PC_READ_STR, cmd_LOAD_PC_STR,
|
|
|
|
// do_READ_PC_STR, do_read_dp_str,
|
|
|
|
// do_cmd_strobe, do_run_addr_loop, do_read_strobe,
|
|
|
|
// strobe_on, o_bus_strobe);
|
|
|
|
|
2019-02-20 16:21:39 +01:00
|
|
|
/*
|
|
|
|
* debug conditions for configure
|
|
|
|
*/
|
|
|
|
|
|
|
|
// $monitor({"BUS - clk %b | ph %0d | osta %b | iabs %b | ",
|
|
|
|
// "i_cmd_config %b | cmd_CONFIGURE_F0 %b | is_loop_finished %b | cmd_CONFIGURE_F1 %b | cmd_PC_READ_F %b"},
|
|
|
|
// i_clk, i_phase, o_stall_alu, i_alu_busy,
|
|
|
|
// i_cmd_config, cmd_CONFIGURE_F0, is_loop_finished, cmd_CONFIGURE_F1, cmd_PC_READ_F);
|
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
/*
|
|
|
|
* debug conditions for reset
|
|
|
|
*/
|
|
|
|
// $monitor({"BUS - clk %b | ph %0d | osta %b | iabs %b | ",
|
|
|
|
// "i_cmd_reset %b | cmd_RESET_F %b | cmd_PC_READ_F %b"},
|
|
|
|
// i_clk, i_phase, o_stall_alu, i_alu_busy,
|
|
|
|
// i_cmd_reset, cmd_RESET_F, cmd_PC_READ_F);
|
2019-02-16 22:38:44 +01:00
|
|
|
`endif
|
|
|
|
end
|
|
|
|
|
|
|
|
always @(posedge i_clk) begin
|
2019-02-17 08:35:26 +01:00
|
|
|
if (i_reset) begin
|
2019-02-19 16:17:35 +01:00
|
|
|
last_cmd <= 0;
|
|
|
|
o_stall_alu <= 1;
|
|
|
|
o_bus_reset <= 1;
|
|
|
|
strobe_on <= 0;
|
|
|
|
o_bus_cmd_data <= 1; // 1 is the default level
|
|
|
|
bus_out_of_reset <= 1;
|
|
|
|
// local states
|
|
|
|
|
|
|
|
// address loop
|
|
|
|
init_addr_loop <= 0;
|
|
|
|
run_addr_loop <= 0;
|
|
|
|
addr_loop_counter <= 0;
|
|
|
|
addr_loop_done <= 0;
|
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
cmd_PC_READ_F <= 0;
|
2019-02-20 16:21:39 +01:00
|
|
|
cmd_DP_READ_F <= 0;
|
|
|
|
cmd_DP_WRITE_F0 <= 0;
|
|
|
|
cmd_DP_WRITE_F1 <= 0;
|
2019-02-20 09:20:16 +01:00
|
|
|
cmd_LOAD_PC_F <= 0;
|
2019-02-20 16:21:39 +01:00
|
|
|
cmd_LOAD_DP_F <= 0;
|
|
|
|
cmd_CONFIGURE_F0 <= 0;
|
|
|
|
cmd_CONFIGURE_F1 <= 0;
|
2019-02-20 09:20:16 +01:00
|
|
|
cmd_RESET_F <= 0;
|
2019-02-19 16:17:35 +01:00
|
|
|
end
|
2019-02-17 19:29:39 +01:00
|
|
|
|
2019-02-19 16:17:35 +01:00
|
|
|
if (reset_bus) begin
|
|
|
|
$display("reset bus");
|
|
|
|
strobe_on <= 1;
|
2019-02-17 08:35:26 +01:00
|
|
|
end
|
2019-02-16 22:38:44 +01:00
|
|
|
|
2019-02-19 16:17:35 +01:00
|
|
|
if (bus_start) begin
|
|
|
|
$display("bus start");
|
|
|
|
strobe_on <= 0;
|
|
|
|
o_bus_reset <= 0;
|
|
|
|
bus_out_of_reset <= 0;
|
|
|
|
o_stall_alu <= 0;
|
2019-02-18 17:38:25 +01:00
|
|
|
end
|
|
|
|
|
2019-02-17 08:35:26 +01:00
|
|
|
/*
|
2019-02-19 16:17:35 +01:00
|
|
|
* here starts the "FUN"
|
2019-02-17 08:35:26 +01:00
|
|
|
*
|
|
|
|
*/
|
2019-02-19 16:17:35 +01:00
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
if (cmd_PC_READ_0) begin
|
2019-02-19 16:17:35 +01:00
|
|
|
$display("BUS_CTRL %1d: [%d] PC_READ", i_phase, i_cycle_ctr);
|
2019-02-20 09:20:16 +01:00
|
|
|
cmd_PC_READ_F <= 1;
|
2019-02-19 16:17:35 +01:00
|
|
|
last_cmd <= `BUSCMD_PC_READ;
|
|
|
|
o_bus_data <= `BUSCMD_PC_READ;
|
|
|
|
o_bus_cmd_data <= 0;
|
|
|
|
o_stall_alu <= 1;
|
2019-02-18 17:38:25 +01:00
|
|
|
end
|
2019-02-17 08:35:26 +01:00
|
|
|
|
2019-02-20 16:21:39 +01:00
|
|
|
/*
|
|
|
|
* DP_WRITE Functions
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (cmd_DP_WRITE_0) begin
|
2019-02-19 16:17:35 +01:00
|
|
|
$display("BUS_CTRL %1d: [%d] DP_WRITE", i_phase, i_cycle_ctr);
|
2019-02-20 16:21:39 +01:00
|
|
|
cmd_DP_WRITE_F0 <= 1;
|
|
|
|
last_cmd <= `BUSCMD_DP_WRITE;
|
|
|
|
o_bus_data <= `BUSCMD_DP_WRITE;
|
|
|
|
o_bus_cmd_data <= 0;
|
|
|
|
o_stall_alu <= 1;
|
2019-02-20 09:20:16 +01:00
|
|
|
end
|
|
|
|
|
2019-02-20 16:21:39 +01:00
|
|
|
if (cmd_DP_WRITE_1) begin
|
|
|
|
$display("BUS_CTRL %1d: [%d] cmd_DP_WRITE_1 (sets cmd_DP_WRITE_F1)", i_phase, i_cycle_ctr);
|
|
|
|
cmd_DP_WRITE_F1 <= 1;
|
|
|
|
o_stall_alu <= 1;
|
2019-02-19 16:17:35 +01:00
|
|
|
end
|
2019-02-17 12:05:38 +01:00
|
|
|
|
2019-02-20 16:21:39 +01:00
|
|
|
if (cmd_DP_WRITE_US0) begin
|
|
|
|
$display("BUS_CTRL %1d: [%d] cmd_DP_WRITE_US0", i_phase, i_cycle_ctr);
|
|
|
|
end
|
2019-02-20 09:20:16 +01:00
|
|
|
|
2019-02-20 16:21:39 +01:00
|
|
|
if (cmd_DP_WRITE_US1) begin
|
|
|
|
$display("BUS_CTRL %1d: [%d] cmd_DP_WRITE_US1", i_phase, i_cycle_ctr);
|
2019-02-19 16:17:35 +01:00
|
|
|
end
|
2019-02-17 12:05:38 +01:00
|
|
|
|
2019-02-20 16:21:39 +01:00
|
|
|
if (cmd_DP_WRITE_C) begin
|
|
|
|
$display("BUS_CTRL %1d: [%d] cmd_DP_WRITE_C", i_phase, i_cycle_ctr);
|
|
|
|
end
|
|
|
|
|
|
|
|
/*
|
|
|
|
* LOAD_PC / LOAD_DP
|
|
|
|
*/
|
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
if (cmd_LOAD_PC_0) begin
|
2019-02-19 16:17:35 +01:00
|
|
|
$display("BUS_CTRL %1d: [%d] LOAD_PC [%5h]", i_phase, i_cycle_ctr, i_address);
|
2019-02-20 09:20:16 +01:00
|
|
|
cmd_LOAD_PC_F <= 1;
|
2019-02-19 16:17:35 +01:00
|
|
|
last_cmd <= `BUSCMD_LOAD_PC;
|
|
|
|
o_bus_data <= `BUSCMD_LOAD_PC;
|
|
|
|
o_bus_cmd_data <= 0;
|
|
|
|
o_stall_alu <= 1;
|
|
|
|
init_addr_loop <= 1;
|
2019-02-17 19:29:39 +01:00
|
|
|
end
|
2019-02-17 12:05:38 +01:00
|
|
|
|
2019-02-20 16:21:39 +01:00
|
|
|
if (cmd_LOAD_DP_0) begin
|
2019-02-19 16:17:35 +01:00
|
|
|
$display("BUS_CTRL %1d: [%d] LOAD_DP [%5h]", i_phase, i_cycle_ctr, i_address);
|
2019-02-20 16:21:39 +01:00
|
|
|
cmd_LOAD_DP_F <= 1;
|
2019-02-19 16:17:35 +01:00
|
|
|
last_cmd <= `BUSCMD_LOAD_DP;
|
|
|
|
o_bus_data <= `BUSCMD_LOAD_DP;
|
|
|
|
o_bus_cmd_data <= 0;
|
|
|
|
o_stall_alu <= 1;
|
|
|
|
init_addr_loop <= 1;
|
|
|
|
end
|
2019-02-16 22:38:44 +01:00
|
|
|
|
2019-02-19 16:17:35 +01:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
2019-02-18 17:38:25 +01:00
|
|
|
|
2019-02-20 16:21:39 +01:00
|
|
|
if (cmd_CONFIGURE_0) begin
|
2019-02-19 16:17:35 +01:00
|
|
|
$display("BUS_CTRL %1d: [%d] CONFIGURE [%5h]", i_phase, i_cycle_ctr, i_address);
|
2019-02-20 16:21:39 +01:00
|
|
|
cmd_CONFIGURE_F0 <= 1;
|
|
|
|
last_cmd <= `BUSCMD_CONFIGURE;
|
|
|
|
o_bus_data <= `BUSCMD_CONFIGURE;
|
|
|
|
o_bus_cmd_data <= 0;
|
|
|
|
o_stall_alu <= 1;
|
|
|
|
init_addr_loop <= 1;
|
2019-02-19 16:17:35 +01:00
|
|
|
end
|
2019-02-17 12:05:38 +01:00
|
|
|
|
2019-02-20 16:21:39 +01:00
|
|
|
if (cmd_CONFIGURE_1) begin
|
|
|
|
$display("BUS_CTRL %1d: [%d] set cmd_CONFIGURE_F1", i_phase, i_cycle_ctr);
|
|
|
|
cmd_CONFIGURE_F1 <= 1;
|
2019-02-19 16:17:35 +01:00
|
|
|
end
|
2019-02-18 17:38:25 +01:00
|
|
|
|
2019-02-19 16:17:35 +01:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
2019-02-18 17:38:25 +01:00
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
if (cmd_RESET_ST0) begin
|
2019-02-19 16:17:35 +01:00
|
|
|
// $display("BUS_CTRL %1d: [%d] reset stall", i_phase, i_cycle_ctr);
|
|
|
|
o_stall_alu <= 1;
|
|
|
|
end
|
2019-02-18 17:38:25 +01:00
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
if (cmd_RESET_0) begin
|
2019-02-19 16:17:35 +01:00
|
|
|
$display("BUS_CTRL %1d: [%d] RESET", i_phase, i_cycle_ctr);
|
2019-02-20 09:20:16 +01:00
|
|
|
cmd_RESET_F <= 1;
|
2019-02-19 16:17:35 +01:00
|
|
|
last_cmd <= `BUSCMD_RESET;
|
|
|
|
o_bus_data <= `BUSCMD_RESET;
|
|
|
|
o_bus_cmd_data <= 0;
|
|
|
|
o_stall_alu <= 1;
|
|
|
|
end
|
2019-02-18 17:38:25 +01:00
|
|
|
|
2019-02-20 16:21:39 +01:00
|
|
|
/****************************************************************************
|
|
|
|
* Address loop handling
|
|
|
|
*
|
|
|
|
*
|
|
|
|
***************************************************************************/
|
2019-02-18 17:38:25 +01:00
|
|
|
|
2019-02-19 16:17:35 +01:00
|
|
|
if (do_init_addr_loop) begin
|
|
|
|
// $display("BUS_CTRL %1d: [%d] init addr loop", i_phase, i_cycle_ctr);
|
|
|
|
addr_loop_done <= 0;
|
|
|
|
addr_loop_counter <= 0;
|
|
|
|
run_addr_loop <= 1;
|
|
|
|
init_addr_loop <= 0;
|
|
|
|
end
|
2019-02-18 11:36:28 +01:00
|
|
|
|
2019-02-19 16:17:35 +01:00
|
|
|
if (do_run_addr_loop) begin
|
|
|
|
$write("BUS_CTRL %1d: [%d] ADDR(%0d)-> %h ",
|
|
|
|
i_phase, i_cycle_ctr, addr_loop_counter,
|
|
|
|
i_address[addr_loop_counter*4+:4]);
|
|
|
|
if (will_loop_finish) $write("done");
|
|
|
|
$write("\n");
|
|
|
|
|
|
|
|
o_bus_data <= i_address[addr_loop_counter*4+:4];
|
|
|
|
// clean up at the end of loop
|
|
|
|
addr_loop_counter <= addr_loop_counter + 1;
|
|
|
|
run_addr_loop <= !will_loop_finish;
|
|
|
|
addr_loop_done <= will_loop_finish;
|
2019-02-18 11:36:28 +01:00
|
|
|
end
|
2019-02-16 22:38:44 +01:00
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
/*
|
|
|
|
* automatic PC_READ after LOAD_PC
|
|
|
|
*
|
|
|
|
*/
|
2019-02-19 16:17:35 +01:00
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
if (do_auto_PC_READ_0) begin
|
2019-02-19 16:17:35 +01:00
|
|
|
$display("BUS_CTRL %1d: [%d] auto PC_READ", i_phase, i_cycle_ctr);
|
|
|
|
last_cmd <= `BUSCMD_PC_READ;
|
2019-02-17 15:03:36 +01:00
|
|
|
end
|
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
`ifdef DEBUG_CTRL
|
|
|
|
if (do_auto_PC_READ_US0) begin
|
|
|
|
$display("BUS_CTRL %1d: [%d] auto PC_READ - unstall", i_phase, i_cycle_ctr);
|
|
|
|
end
|
|
|
|
`endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* automatic DP_READ after LOAD_DP
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2019-02-20 16:21:39 +01:00
|
|
|
if (do_auto_DP_READ_0) begin
|
2019-02-19 16:17:35 +01:00
|
|
|
$display("BUS_CTRL %1d: [%d] auto DP_READ", i_phase, i_cycle_ctr);
|
2019-02-20 16:21:39 +01:00
|
|
|
cmd_DP_READ_F <= 1;
|
|
|
|
last_cmd <= `BUSCMD_DP_READ;
|
2019-02-20 09:20:16 +01:00
|
|
|
end
|
|
|
|
|
2019-02-20 16:21:39 +01:00
|
|
|
// if (do_auto_DP_READ_US0) begin
|
|
|
|
// $display("BUS_CTRL %1d: [%d] auto DP_READ unstall (does nothing)", i_phase, i_cycle_ctr);
|
|
|
|
// end
|
2019-02-18 11:36:28 +01:00
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
|
|
|
|
|
2019-02-19 16:17:35 +01:00
|
|
|
if (do_reset_loop_counter) begin
|
|
|
|
// $display("BUS_CTRL %1d: [%d] reset loop counter", i_phase, i_cycle_ctr);
|
|
|
|
addr_loop_counter <= 0;
|
2019-02-18 17:38:25 +01:00
|
|
|
end
|
2019-02-17 20:23:43 +01:00
|
|
|
|
2019-02-18 17:38:25 +01:00
|
|
|
if (do_unstall) begin
|
2019-02-20 09:20:16 +01:00
|
|
|
`ifdef DEBUG_CTRL
|
2019-02-19 16:17:35 +01:00
|
|
|
$display("BUS_CTRL %1d: [%d] remove stall", i_phase, i_cycle_ctr);
|
2019-02-20 09:20:16 +01:00
|
|
|
`endif
|
2019-02-19 16:17:35 +01:00
|
|
|
o_stall_alu <= 0;
|
|
|
|
end
|
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
if (do_load_clean) begin
|
|
|
|
$display("BUS_CTRL %1d: [%d] cleanup after load", i_phase, i_cycle_ctr);
|
|
|
|
cmd_LOAD_PC_F <= 0;
|
|
|
|
end
|
|
|
|
|
2019-02-19 16:17:35 +01:00
|
|
|
if (do_clean) begin
|
2019-02-20 16:21:39 +01:00
|
|
|
$display("BUS_CTRL %1d: [%d] cleanup", i_phase, i_cycle_ctr);
|
2019-02-20 09:20:16 +01:00
|
|
|
cmd_PC_READ_F <= 0;
|
2019-02-20 16:21:39 +01:00
|
|
|
do_read_dp_s <= 0;
|
|
|
|
cmd_DP_WRITE_F0 <= 0;
|
|
|
|
cmd_DP_WRITE_F1 <= 0;
|
|
|
|
cmd_CONFIGURE_F0 <= 0;
|
|
|
|
cmd_CONFIGURE_F1 <= 0;
|
2019-02-20 09:20:16 +01:00
|
|
|
cmd_RESET_F <= 0;
|
2019-02-18 17:38:25 +01:00
|
|
|
end
|
2019-02-17 20:23:43 +01:00
|
|
|
|
2019-02-18 17:38:25 +01:00
|
|
|
/*
|
2019-02-19 16:17:35 +01:00
|
|
|
*
|
2019-02-20 09:20:16 +01:00
|
|
|
* bus actions
|
2019-02-19 16:17:35 +01:00
|
|
|
*
|
2019-02-18 17:38:25 +01:00
|
|
|
*/
|
2019-02-17 19:29:39 +01:00
|
|
|
|
2019-02-19 16:17:35 +01:00
|
|
|
if (do_strobe) begin
|
2019-02-20 09:20:16 +01:00
|
|
|
// $display("S");
|
2019-02-19 16:17:35 +01:00
|
|
|
strobe_on <= 1;
|
2019-02-18 17:38:25 +01:00
|
|
|
end
|
2019-02-17 15:03:36 +01:00
|
|
|
|
2019-02-20 09:20:16 +01:00
|
|
|
if (do_read_dp) begin
|
|
|
|
// $display("set do_read_dp_s");
|
|
|
|
do_read_dp_s <= 1;
|
|
|
|
end
|
|
|
|
|
|
|
|
if (do_read) begin
|
2019-02-19 16:17:35 +01:00
|
|
|
o_nibble <= i_bus_data;
|
|
|
|
$display("BUS_CTRL %1d: [%d] READ %h", i_phase, i_cycle_ctr, i_bus_data);
|
|
|
|
end
|
2019-02-18 17:38:25 +01:00
|
|
|
|
2019-02-20 16:21:39 +01:00
|
|
|
if (do_WRITE_DP_0) begin
|
2019-02-19 16:17:35 +01:00
|
|
|
$display("BUS_CTRL %1d: [%d] WRITE %h", i_phase, i_cycle_ctr, i_nibble);
|
|
|
|
o_bus_data <= i_nibble;
|
|
|
|
end
|
|
|
|
|
|
|
|
if (do_read_stalled_by_alu) begin
|
|
|
|
$display("BUS_CTRL %1d: [%d] read stall (alu)", i_phase, i_cycle_ctr);
|
|
|
|
end
|
|
|
|
|
|
|
|
if (do_remove_strobe) begin
|
2019-02-20 09:20:16 +01:00
|
|
|
// $display(".s");
|
2019-02-19 16:17:35 +01:00
|
|
|
strobe_on <= 0;
|
|
|
|
o_bus_cmd_data <= 1;
|
2019-02-17 08:35:26 +01:00
|
|
|
end
|
|
|
|
|
2019-02-17 15:03:36 +01:00
|
|
|
|
2019-02-16 22:38:44 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
`endif
|