mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-22 04:47:25 -04:00
Cleanup hwloops, use parameters instead of defines, and also make it
completely generic The only dependency that limits the number of hwloops now is the encoding, the rest adapts automatically
This commit is contained in:
parent
b0a9e37c63
commit
e5bb1447cc
4 changed files with 106 additions and 99 deletions
|
@ -29,26 +29,28 @@
|
|||
`include "defines.sv"
|
||||
|
||||
module riscv_hwloop_controller
|
||||
#(
|
||||
parameter N_REGS = 2
|
||||
)
|
||||
(
|
||||
// from id stage
|
||||
input logic enable_i,
|
||||
input logic [31:0] current_pc_i,
|
||||
input logic [31:0] current_pc_i,
|
||||
|
||||
// from hwloop_regs
|
||||
input logic [`HWLOOP_REGS-1:0] [31:0] hwloop_start_addr_i,
|
||||
input logic [`HWLOOP_REGS-1:0] [31:0] hwloop_end_addr_i,
|
||||
input logic [`HWLOOP_REGS-1:0] [31:0] hwloop_counter_i,
|
||||
input logic [N_REGS-1:0] [31:0] hwlp_start_addr_i,
|
||||
input logic [N_REGS-1:0] [31:0] hwlp_end_addr_i,
|
||||
input logic [N_REGS-1:0] [31:0] hwlp_counter_i,
|
||||
|
||||
// to hwloop_regs
|
||||
output logic [`HWLOOP_REGS-1:0] hwloop_dec_cnt_o,
|
||||
output logic [N_REGS-1:0] hwlp_dec_cnt_o,
|
||||
|
||||
// to id stage
|
||||
output logic hwloop_jump_o,
|
||||
output logic [31:0] hwloop_targ_addr_o
|
||||
output logic hwlp_jump_o,
|
||||
output logic [31:0] hwlp_targ_addr_o
|
||||
);
|
||||
|
||||
|
||||
logic [`HWLOOP_REGS-1:0] pc_is_end_addr;
|
||||
logic [N_REGS-1:0] pc_is_end_addr;
|
||||
|
||||
// end address detection
|
||||
integer j;
|
||||
|
@ -56,28 +58,25 @@ module riscv_hwloop_controller
|
|||
|
||||
// generate comparators. check for end address and the loop counter
|
||||
genvar i;
|
||||
for (i = 0; i < `HWLOOP_REGS; i++) begin
|
||||
assign pc_is_end_addr[i] = (
|
||||
enable_i
|
||||
&& (current_pc_i == hwloop_end_addr_i[i])
|
||||
&& (hwloop_counter_i[i] > 32'b1)
|
||||
);
|
||||
for (i = 0; i < N_REGS; i++) begin
|
||||
assign pc_is_end_addr[i] = (current_pc_i == hwlp_end_addr_i[i]) &&
|
||||
(hwlp_counter_i[i] > 32'h1);
|
||||
end
|
||||
|
||||
// output signal for ID stage
|
||||
assign hwloop_jump_o = |pc_is_end_addr;
|
||||
assign hwlp_jump_o = (|pc_is_end_addr);
|
||||
|
||||
|
||||
// select corresponding start address and decrement counter
|
||||
always_comb
|
||||
begin
|
||||
hwloop_targ_addr_o = 32'b0;
|
||||
hwloop_dec_cnt_o = '0;
|
||||
hwlp_targ_addr_o = 'x;
|
||||
hwlp_dec_cnt_o = '0;
|
||||
|
||||
for (j = `HWLOOP_REGS-1; j >= 0; j--) begin
|
||||
for (j = N_REGS-1; j >= 0; j--) begin
|
||||
if (pc_is_end_addr[j]) begin
|
||||
hwloop_targ_addr_o = hwloop_start_addr_i[j];
|
||||
hwloop_dec_cnt_o[j] = 1'b1;
|
||||
hwlp_targ_addr_o = hwlp_start_addr_i[j];
|
||||
hwlp_dec_cnt_o[j] = 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -29,40 +29,44 @@
|
|||
`include "defines.sv"
|
||||
|
||||
module riscv_hwloop_regs
|
||||
#(
|
||||
parameter N_REGS = 2,
|
||||
parameter N_REG_BITS = $clog2(N_REGS)
|
||||
)
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst_n,
|
||||
input logic clk,
|
||||
input logic rst_n,
|
||||
|
||||
// from ex stage
|
||||
input logic [31:0] hwloop_start_data_i,
|
||||
input logic [31:0] hwloop_end_data_i,
|
||||
input logic [31:0] hwloop_cnt_data_i,
|
||||
input logic [2:0] hwloop_we_i,
|
||||
input logic [1:0] hwloop_regid_i, // selects the register set
|
||||
input logic [31:0] hwlp_start_data_i,
|
||||
input logic [31:0] hwlp_end_data_i,
|
||||
input logic [31:0] hwlp_cnt_data_i,
|
||||
input logic [2:0] hwlp_we_i,
|
||||
input logic [N_REG_BITS-1:0] hwlp_regid_i, // selects the register set
|
||||
|
||||
// from controller
|
||||
input logic stall_id_i,
|
||||
input logic valid_i,
|
||||
|
||||
// from hwloop controller
|
||||
input logic [`HWLOOP_REGS-1:0] hwloop_dec_cnt_i,
|
||||
input logic [N_REGS-1:0] hwlp_dec_cnt_i,
|
||||
|
||||
// to hwloop controller
|
||||
output logic [`HWLOOP_REGS-1:0] [31:0] hwloop_start_addr_o,
|
||||
output logic [`HWLOOP_REGS-1:0] [31:0] hwloop_end_addr_o,
|
||||
output logic [`HWLOOP_REGS-1:0] [31:0] hwloop_counter_o
|
||||
output logic [N_REGS-1:0] [31:0] hwlp_start_addr_o,
|
||||
output logic [N_REGS-1:0] [31:0] hwlp_end_addr_o,
|
||||
output logic [N_REGS-1:0] [31:0] hwlp_counter_o
|
||||
);
|
||||
|
||||
|
||||
logic [`HWLOOP_REGS-1:0] [31:0] hwloop_start_regs_q;
|
||||
logic [`HWLOOP_REGS-1:0] [31:0] hwloop_end_regs_q;
|
||||
logic [`HWLOOP_REGS-1:0] [31:0] hwloop_counter_regs_q;
|
||||
logic [N_REGS-1:0] [31:0] hwlp_start_q;
|
||||
logic [N_REGS-1:0] [31:0] hwlp_end_q;
|
||||
logic [N_REGS-1:0] [31:0] hwlp_counter_q, hwlp_counter_n;
|
||||
|
||||
int unsigned i;
|
||||
|
||||
|
||||
assign hwloop_start_addr_o = hwloop_start_regs_q;
|
||||
assign hwloop_end_addr_o = hwloop_end_regs_q;
|
||||
assign hwloop_counter_o = hwloop_counter_regs_q;
|
||||
assign hwlp_start_addr_o = hwlp_start_q;
|
||||
assign hwlp_end_addr_o = hwlp_end_q;
|
||||
assign hwlp_counter_o = hwlp_counter_q;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -72,13 +76,11 @@ module riscv_hwloop_regs
|
|||
begin : HWLOOP_REGS_START
|
||||
if (rst_n == 1'b0)
|
||||
begin
|
||||
for(i=0; i<`HWLOOP_REGS; i++) begin
|
||||
hwloop_start_regs_q[i] <= 32'h0000_0000;
|
||||
end
|
||||
hwlp_start_q <= '{default: 32'b0};
|
||||
end
|
||||
else if (hwloop_we_i[0] == 1'b1)
|
||||
else if (hwlp_we_i[0] == 1'b1)
|
||||
begin
|
||||
hwloop_start_regs_q[hwloop_regid_i] <= hwloop_start_data_i;
|
||||
hwlp_start_q[hwlp_regid_i] <= hwlp_start_data_i;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -90,13 +92,11 @@ module riscv_hwloop_regs
|
|||
begin : HWLOOP_REGS_END
|
||||
if (rst_n == 1'b0)
|
||||
begin
|
||||
for(i=0; i<`HWLOOP_REGS; i++) begin
|
||||
hwloop_end_regs_q[i] <= 32'h0000_0000;
|
||||
end
|
||||
hwlp_end_q <= '{default: 32'b0};
|
||||
end
|
||||
else if (hwloop_we_i[1] == 1'b1)
|
||||
else if (hwlp_we_i[1] == 1'b1)
|
||||
begin
|
||||
hwloop_end_regs_q[hwloop_regid_i] <= hwloop_end_data_i;
|
||||
hwlp_end_q[hwlp_regid_i] <= hwlp_end_data_i;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -104,24 +104,27 @@ module riscv_hwloop_regs
|
|||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// HWLOOP counter register with decrement logic //
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
genvar k;
|
||||
for (k = 0; k < N_REGS; k++) begin
|
||||
assign hwlp_counter_n[k] = hwlp_counter_q[k] - 1;
|
||||
end
|
||||
|
||||
always_ff @(posedge clk, negedge rst_n)
|
||||
begin : HWLOOP_REGS_COUNTER
|
||||
if (rst_n == 1'b0)
|
||||
begin
|
||||
for (i=0; i<`HWLOOP_REGS; i++) begin
|
||||
hwloop_counter_regs_q[i] <= 32'h0000_0000;
|
||||
end
|
||||
hwlp_counter_q <= '{default: 32'b0};
|
||||
end
|
||||
else if (hwloop_we_i[2] == 1'b1) // potential contention problem here!
|
||||
else if (hwlp_we_i[2] == 1'b1) // potential contention problem here!
|
||||
begin
|
||||
hwloop_counter_regs_q[hwloop_regid_i] <= hwloop_cnt_data_i;
|
||||
hwlp_counter_q[hwlp_regid_i] <= hwlp_cnt_data_i;
|
||||
end
|
||||
else
|
||||
begin
|
||||
for (i=0; i<`HWLOOP_REGS; i++)
|
||||
for (i = 0; i < N_REGS; i++)
|
||||
begin
|
||||
if ((hwloop_dec_cnt_i[i] == 1'b1) && (stall_id_i == 1'b0))
|
||||
hwloop_counter_regs_q[i] <= hwloop_counter_regs_q[i] - 1;
|
||||
if (hwlp_dec_cnt_i[i] && valid_i)
|
||||
hwlp_counter_q[i] <= hwlp_counter_n;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
83
id_stage.sv
83
id_stage.sv
|
@ -34,6 +34,10 @@
|
|||
`include "defines.sv"
|
||||
|
||||
module riscv_id_stage
|
||||
#(
|
||||
parameter N_HWLP_REGS = 2,
|
||||
parameter N_HWLP_REG_BITS = $clog2(N_HWLP_REGS)
|
||||
)
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst_n,
|
||||
|
@ -253,23 +257,23 @@ module riscv_id_stage
|
|||
logic data_req_id;
|
||||
|
||||
// hwloop signals
|
||||
logic [1:0] hwloop_regid;
|
||||
logic [2:0] hwloop_we;
|
||||
logic hwloop_jump;
|
||||
logic hwloop_target_mux_sel;
|
||||
logic hwloop_start_mux_sel;
|
||||
logic hwloop_cnt_mux_sel;
|
||||
logic [N_HWLP_REG_BITS-1:0] hwloop_regid;
|
||||
logic [2:0] hwloop_we;
|
||||
logic hwloop_jump;
|
||||
logic hwloop_target_mux_sel;
|
||||
logic hwloop_start_mux_sel;
|
||||
logic hwloop_cnt_mux_sel;
|
||||
|
||||
logic [31:0] hwloop_target;
|
||||
logic [31:0] hwloop_start;
|
||||
logic [31:0] hwloop_end;
|
||||
logic [31:0] hwloop_cnt;
|
||||
logic [31:0] hwloop_target;
|
||||
logic [31:0] hwloop_start;
|
||||
logic [31:0] hwloop_end;
|
||||
logic [31:0] hwloop_cnt;
|
||||
|
||||
// hwloop reg signals
|
||||
logic [`HWLOOP_REGS-1:0] hwloop_dec_cnt;
|
||||
logic [`HWLOOP_REGS-1:0] [31:0] hwloop_start_addr;
|
||||
logic [`HWLOOP_REGS-1:0] [31:0] hwloop_end_addr;
|
||||
logic [`HWLOOP_REGS-1:0] [31:0] hwloop_counter;
|
||||
logic [N_HWLP_REGS-1:0] hwloop_dec_cnt;
|
||||
logic [N_HWLP_REGS-1:0] [31:0] hwloop_start_addr;
|
||||
logic [N_HWLP_REGS-1:0] [31:0] hwloop_end_addr;
|
||||
logic [N_HWLP_REGS-1:0] [31:0] hwloop_counter;
|
||||
|
||||
// CSR control
|
||||
logic csr_access;
|
||||
|
@ -759,49 +763,56 @@ module riscv_id_stage
|
|||
// //
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
riscv_hwloop_controller hwloop_controller_i
|
||||
riscv_hwloop_controller
|
||||
#(
|
||||
.N_REGS ( N_HWLP_REGS )
|
||||
)
|
||||
hwloop_controller_i
|
||||
(
|
||||
// from ID stage
|
||||
.enable_i ( 1'b1 ),
|
||||
.current_pc_i ( current_pc_if_i ),
|
||||
.current_pc_i ( current_pc_if_i ),
|
||||
|
||||
// to IF stage/controller
|
||||
.hwloop_jump_o ( hwloop_jump ),
|
||||
.hwloop_targ_addr_o ( hwloop_targ_addr_o ),
|
||||
.hwlp_jump_o ( hwloop_jump ),
|
||||
.hwlp_targ_addr_o ( hwloop_targ_addr_o ),
|
||||
|
||||
// from hwloop_regs
|
||||
.hwloop_start_addr_i ( hwloop_start_addr ),
|
||||
.hwloop_end_addr_i ( hwloop_end_addr ),
|
||||
.hwloop_counter_i ( hwloop_counter ),
|
||||
.hwlp_start_addr_i ( hwloop_start_addr ),
|
||||
.hwlp_end_addr_i ( hwloop_end_addr ),
|
||||
.hwlp_counter_i ( hwloop_counter ),
|
||||
|
||||
// to hwloop_regs
|
||||
.hwloop_dec_cnt_o ( hwloop_dec_cnt )
|
||||
.hwlp_dec_cnt_o ( hwloop_dec_cnt )
|
||||
);
|
||||
|
||||
assign hwloop_jump_o = hwloop_jump;
|
||||
|
||||
riscv_hwloop_regs hwloop_regs_i
|
||||
riscv_hwloop_regs
|
||||
#(
|
||||
.N_REGS ( N_HWLP_REGS )
|
||||
)
|
||||
hwloop_regs_i
|
||||
(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
|
||||
// from ID
|
||||
.hwloop_start_data_i ( hwloop_start ),
|
||||
.hwloop_end_data_i ( hwloop_end ),
|
||||
.hwloop_cnt_data_i ( hwloop_cnt ),
|
||||
.hwloop_we_i ( hwloop_we ),
|
||||
.hwloop_regid_i ( hwloop_regid ),
|
||||
.hwlp_start_data_i ( hwloop_start ),
|
||||
.hwlp_end_data_i ( hwloop_end ),
|
||||
.hwlp_cnt_data_i ( hwloop_cnt ),
|
||||
.hwlp_we_i ( hwloop_we ),
|
||||
.hwlp_regid_i ( hwloop_regid ),
|
||||
|
||||
// from controller
|
||||
.stall_id_i ( ~instr_valid_i ),
|
||||
.valid_i ( instr_valid_i ),
|
||||
|
||||
// to hwloop controller
|
||||
.hwloop_start_addr_o ( hwloop_start_addr ),
|
||||
.hwloop_end_addr_o ( hwloop_end_addr ),
|
||||
.hwloop_counter_o ( hwloop_counter ),
|
||||
.hwlp_start_addr_o ( hwloop_start_addr ),
|
||||
.hwlp_end_addr_o ( hwloop_end_addr ),
|
||||
.hwlp_counter_o ( hwloop_counter ),
|
||||
|
||||
// from hwloop controller
|
||||
.hwloop_dec_cnt_i ( hwloop_dec_cnt )
|
||||
.hwlp_dec_cnt_i ( hwloop_dec_cnt )
|
||||
);
|
||||
|
||||
|
||||
|
|
|
@ -319,12 +319,6 @@
|
|||
`define EXC_OFF_LSUERR 8'h8c
|
||||
|
||||
|
||||
// Hardware loop registers
|
||||
// Caution: Changing this parameter is not sufficient to increase the number of
|
||||
// hwloop registers! There are adjustments needed in the controller (decoder).
|
||||
`define HWLOOP_REGS 2
|
||||
|
||||
|
||||
// Debug module
|
||||
`define N_WP 2 // #Watchpoints
|
||||
`define DCR_DP 0
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue