Commit edf32c1b authored by Tristan Gingold's avatar Tristan Gingold

urv_fetch: add im_rd_o output

This signal is active when an instruction is read from memory.
This also indicates when the bus is not used (and therefore could be
used by a scrubber)
parent 10f8dc29
...@@ -46,6 +46,7 @@ module urv_cpu ...@@ -46,6 +46,7 @@ module urv_cpu
// instruction mem I/F // instruction mem I/F
output [31:0] im_addr_o, output [31:0] im_addr_o,
output im_rd_o,
input [31:0] im_data_i, input [31:0] im_data_i,
input im_valid_i, input im_valid_i,
...@@ -167,6 +168,7 @@ module urv_cpu ...@@ -167,6 +168,7 @@ module urv_cpu
// instruction memory // instruction memory
.im_addr_o(im_addr_o), .im_addr_o(im_addr_o),
.im_rd_o(im_rd_o),
.im_data_i(im_data_i), .im_data_i(im_data_i),
.im_valid_i(im_valid_i), .im_valid_i(im_valid_i),
......
...@@ -35,6 +35,7 @@ module urv_fetch ...@@ -35,6 +35,7 @@ module urv_fetch
// Instruction memory // Instruction memory
output [31:0] im_addr_o, output [31:0] im_addr_o,
output im_rd_o,
input [31:0] im_data_i, input [31:0] im_data_i,
input im_valid_i, input im_valid_i,
...@@ -64,18 +65,22 @@ module urv_fetch ...@@ -64,18 +65,22 @@ module urv_fetch
reg [31:0] pc_next; reg [31:0] pc_next;
reg dbg_mode; reg dbg_mode;
reg [2:0] pipeline_cnt; reg [2:0] pipeline_cnt;
wire frozen;
assign frozen = (f_stall_i
|| dbg_mode || dbg_force_i || pipeline_cnt != 0);
always@* always@*
if( x_bra_i ) if (x_bra_i)
pc_next <= x_pc_bra_i; pc_next <= x_pc_bra_i;
else if (!rst_d || f_stall_i || !im_valid_i else if (rst_d || frozen || !im_valid_i)
|| dbg_mode || dbg_force_i || pipeline_cnt != 0)
pc_next <= pc; pc_next <= pc;
else else
pc_next <= pc + 4; pc_next <= pc + 4;
// Start fetching the next instruction // Start fetching the next instruction
assign im_addr_o = pc_next; assign im_addr_o = pc_next;
assign im_rd_o = x_bra_i || !(frozen || rst_i);
assign dbg_enabled_o = dbg_mode; assign dbg_enabled_o = dbg_mode;
assign dbg_insn_ready_o = pipeline_cnt == 4; assign dbg_insn_ready_o = pipeline_cnt == 4;
...@@ -97,11 +102,11 @@ module urv_fetch ...@@ -97,11 +102,11 @@ module urv_fetch
// The instruction won't be valid on the next cycle, as the // The instruction won't be valid on the next cycle, as the
// instruction memory is registered. // instruction memory is registered.
rst_d <= 0; rst_d <= 1;
end end
else else
begin begin
rst_d <= 1; rst_d <= 0;
if (!f_stall_i) if (!f_stall_i)
begin begin
...@@ -111,6 +116,8 @@ module urv_fetch ...@@ -111,6 +116,8 @@ module urv_fetch
if(!dbg_mode if(!dbg_mode
&& (dbg_force_i || x_dbg_toggle_i || pipeline_cnt != 0)) && (dbg_force_i || x_dbg_toggle_i || pipeline_cnt != 0))
begin begin
// Enter or entering in debug mode
// Stall until the debug mode is set (pipeline flushed). // Stall until the debug mode is set (pipeline flushed).
f_valid_o <= 0; f_valid_o <= 0;
// Ebreak enters directly in the debug mode. As it is // Ebreak enters directly in the debug mode. As it is
...@@ -125,6 +132,7 @@ module urv_fetch ...@@ -125,6 +132,7 @@ module urv_fetch
end end
else if(dbg_mode) else if(dbg_mode)
begin begin
// In debug mode
if (x_dbg_toggle_i) if (x_dbg_toggle_i)
begin begin
// Leave debug mode immediately. // Leave debug mode immediately.
...@@ -147,7 +155,8 @@ module urv_fetch ...@@ -147,7 +155,8 @@ module urv_fetch
begin begin
f_ir_o <= im_data_i; f_ir_o <= im_data_i;
// A branch invalidate the current instruction. // A branch invalidate the current instruction.
f_valid_o <= (rst_d && !x_bra_i); // Not valid on the first cycle
f_valid_o <= (!rst_d && !x_bra_i);
end end
else else
begin begin
......
...@@ -15,16 +15,17 @@ package urv_pkg is ...@@ -15,16 +15,17 @@ package urv_pkg is
rst_i : in std_logic; rst_i : in std_logic;
irq_i : in std_logic; irq_i : in std_logic;
-- instruction mem I/F -- instruction mem I/F
im_addr_o : out std_logic_vector (31 downto 0); im_addr_o : out std_logic_vector (31 downto 0);
im_data_i : in std_logic_vector (31 downto 0); im_rd_o : out std_logic;
im_valid_i : in std_logic; im_data_i : in std_logic_vector (31 downto 0);
im_valid_i : in std_logic;
-- data mem I/F -- data mem I/F
-- The interface is pipelined: store/load are asserted for one cycle -- The interface is pipelined: store/load are asserted for one cycle
-- and then store_done/load_done is awaited. -- and then store_done/load_done is awaited.
dm_addr_o : out std_logic_vector (31 downto 0); dm_addr_o : out std_logic_vector (31 downto 0);
dm_data_s_o : out std_logic_vector (31 downto 0); dm_data_s_o : out std_logic_vector (31 downto 0);
dm_data_l_i : in std_logic_vector (31 downto 0); dm_data_l_i : in std_logic_vector (31 downto 0);
dm_data_select_o : out std_logic_vector (3 downto 0); dm_data_select_o : out std_logic_vector (3 downto 0);
dm_store_o : out std_logic; dm_store_o : out std_logic;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment