mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-24 13:57:19 -04:00
98 lines
3.5 KiB
Systemverilog
98 lines
3.5 KiB
Systemverilog
// Copyright 2015 ETH Zurich and University of Bologna.
|
|
// Copyright and related rights are licensed under the Solderpad Hardware
|
|
// License, Version 0.51 (the “License”); you may not use this file except in
|
|
// compliance with the License. You may obtain a copy of the License at
|
|
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
|
// or agreed to in writing, software, hardware and materials distributed under
|
|
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
|
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
// specific language governing permissions and limitations under the License.
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Engineer: Michael Gautschi - gautschi@iis.ee.ethz.ch //
|
|
// //
|
|
// Design Name: hwloop controller //
|
|
// Project Name: RI5CY //
|
|
// Language: SystemVerilog //
|
|
// //
|
|
// Description: Hardware loop controller unit. This unit is responsible to //
|
|
// handle hardware loops. Tasks are: //
|
|
// a) compare PC to all stored end addresses //
|
|
// b) jump to the right start address if counter =/ 0 //
|
|
// //
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
module riscv_hwloop_controller
|
|
#(
|
|
parameter N_REGS = 2
|
|
)
|
|
(
|
|
// from id stage
|
|
input logic [31:0] current_pc_i,
|
|
|
|
// from hwloop_regs
|
|
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 [N_REGS-1:0] hwlp_dec_cnt_o,
|
|
|
|
// from pipeline stages
|
|
input logic [N_REGS-1:0] hwlp_dec_cnt_id_i,
|
|
|
|
// to id stage
|
|
output logic hwlp_jump_o,
|
|
output logic [31:0] hwlp_targ_addr_o
|
|
);
|
|
|
|
|
|
logic [N_REGS-1:0] pc_is_end_addr;
|
|
|
|
// end address detection
|
|
integer j;
|
|
|
|
|
|
// generate comparators. check for end address and the loop counter
|
|
genvar i;
|
|
generate
|
|
for (i = 0; i < N_REGS; i++) begin
|
|
always @(*)
|
|
begin
|
|
pc_is_end_addr[i] = 1'b0;
|
|
|
|
if (current_pc_i == hwlp_end_addr_i[i]) begin
|
|
if (hwlp_counter_i[i][31:2] != 30'h0) begin
|
|
pc_is_end_addr[i] = 1'b1;
|
|
end else begin
|
|
// hwlp_counter_i[i][31:2] == 32'h0
|
|
case (hwlp_counter_i[i][1:0])
|
|
2'b11: pc_is_end_addr[i] = 1'b1;
|
|
2'b10: pc_is_end_addr[i] = ~hwlp_dec_cnt_id_i[i]; // only when there is nothing in flight
|
|
2'b01, 2'b00: pc_is_end_addr[i] = 1'b0;
|
|
endcase
|
|
end
|
|
end
|
|
end
|
|
end
|
|
endgenerate
|
|
|
|
// select corresponding start address and decrement counter
|
|
always_comb
|
|
begin
|
|
hwlp_targ_addr_o = 'x;
|
|
hwlp_dec_cnt_o = '0;
|
|
|
|
for (j = 0; j < N_REGS; j++) begin
|
|
if (pc_is_end_addr[j]) begin
|
|
hwlp_targ_addr_o = hwlp_start_addr_i[j];
|
|
hwlp_dec_cnt_o[j] = 1'b1;
|
|
break;
|
|
end
|
|
end
|
|
end
|
|
|
|
// output signal for ID stage
|
|
assign hwlp_jump_o = (|pc_is_end_addr);
|
|
|
|
endmodule
|