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:
Andreas Traber 2015-11-19 11:51:26 +01:00
parent b0a9e37c63
commit e5bb1447cc
4 changed files with 106 additions and 99 deletions

View file

@ -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

View file

@ -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

View file

@ -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 )
);

View file

@ -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