Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
e73baaec2This file is pinned to the selected release. Download the original to open it in your design tool.
// Copyright 2018 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.
`include "common_cells/registers.svh"
// Author: Florian Zaruba, zarubaf@iis.ee.ethz.ch
// Description: Delay (or randomize) AXI-like handshaking
module cc_stream_delay #(
parameter bit StallRandom = 0,
parameter int unsigned FixedDelay = 1,
parameter type payload_t = logic,
parameter logic [15:0] Seed = '0
)(
input logic clk_i, // Clock
input logic rst_ni, // Asynchronous reset active low
input logic clr_i, // Synchronous clear active high
input payload_t payload_i,
output logic ready_o,
input logic valid_i,
output payload_t payload_o,
input logic ready_i,
output logic valid_o
);
if (FixedDelay == 0 && !StallRandom) begin : gen_pass_through
assign ready_o = ready_i;
assign valid_o = valid_i;
assign payload_o = payload_i;
end else begin : gen_delay
localparam int unsigned CounterBits = 32;
typedef enum logic [1:0] {
Idle, Valid, Ready
} state_e;
state_e state_d, state_q;
logic load;
logic [CounterBits-1:0] count_out;
logic en;
logic [CounterBits-1:0] counter_load;
assign payload_o = payload_i;
always_comb begin
state_d = state_q;
valid_o = 1'b0;
ready_o = 1'b0;
load = 1'b0;
en = 1'b0;
unique case (state_q)
Idle: begin
if (valid_i) begin
load = 1'b1;
state_d = Valid;
// Just one cycle delay
if (FixedDelay == 1 || (StallRandom && counter_load == 1)) begin
state_d = Ready;
end
if (StallRandom && counter_load == 0) begin
valid_o = 1'b1;
ready_o = ready_i;
if (ready_i) state_d = Idle;
else state_d = Ready;
end
end
end
Valid: begin
en = 1'b1;
if (count_out == 0) begin
state_d = Ready;
end
end
Ready: begin
valid_o = 1'b1;
ready_o = ready_i;
if (ready_i) state_d = Idle;
end
default : /* default */;
endcase
end
if (StallRandom) begin : gen_random_stall
cc_lfsr_16bit #(
.Width ( 16 ),
.Seed ( Seed )
) i_lfsr_16bit (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.clr_i ( clr_i ),
.en_i ( load ),
.refill_way_oh_o ( ),
.refill_way_bin_o ( counter_load )
);
end else begin : gen_fixed_delay
assign counter_load = FixedDelay;
end
cc_counter #(
.Width ( CounterBits )
) i_counter (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.clr_i ( clr_i ),
.en_i ( en ),
.load_i ( load ),
.down_i ( 1'b1 ),
.d_i ( counter_load ),
.q_o ( count_out ),
.overflow_o ( )
);
`FFARNC(state_q, state_d, clr_i, Idle, clk_i, rst_ni)
end
endmodule