stream_filter.sv
ストリームのドロップを制御するシンプルなフィルタモジュールである。
drop_iが1の場合、下流に関係なく上流にreadyをアサートし、validを下流へ伝播しない。
// Stream filter: If `drop_i` is `1`, signal `ready` to the upstream regardless of the downstream, // and do not propagate `valid` downstream. Otherwise, connect upstream to downstream. module stream_filter ( input logic valid_i, output logic ready_o, input logic drop_i, output logic valid_o, input logic ready_i ); assign valid_o = drop_i ? 1'b0 : valid_i; assign ready_o = drop_i ? 1'b1 : ready_i; endmodule
stream_throttle.sv
ストリームのoutstanding転送数を制限するモジュールである。 クレジットカウンタを使用し、最大outstanding転送数をコンパイル時に設定し、実際のoutstanding転送数をランタイムで設定できる。
/// Throttles a ready valid handshaked bus. The maximum number of outstanding transfers have to /// be set as a compile-time parameter, whereas the number of outstanding transfers can be set /// during runtime. This module assumes either in-order processing of the requests or /// indistinguishability of the request/responses. module stream_throttle #( /// The maximum amount of allowable outstanding requests parameter int unsigned MaxNumPending = 1, /// The width of the credit counter (*DO NOT OVERWRITE*) parameter int unsigned CntWidth = cf_math_pkg::idx_width(MaxNumPending), /// The type of the credit counter (*DO NOT OVERWRITE*) parameter type credit_t = logic [CntWidth-1:0] ) ( /// Clock input logic clk_i, /// Asynchronous reset, active low input logic rst_ni, /// Request valid in input logic req_valid_i, /// Request valid out output logic req_valid_o, /// Request ready in input logic req_ready_i, /// Request ready out output logic req_ready_o, /// Response valid in input logic rsp_valid_i, /// Response ready in input logic rsp_ready_i, /// Amount of credit (number of outstanding transfers) input credit_t credit_i ); // we use a credit counter to keep track of how many transfers are pending at any point in // time. Valid is passed-through if there is credit. credit_t credit_d, credit_q; // we have credit available logic credit_available; // implement the counter. If credit is available let the valid pass, else block it. Increment // the counter once a request happens, decrement once a response arrives. Assumes in-order // responses. always_comb begin : proc_credit_counter // default: keep state credit_d = credit_q; // on valid outgoing request: count up if (req_ready_o & req_valid_o) begin credit_d = credit_d + 'd1; end // on valid response: count down if (rsp_valid_i & rsp_ready_i) begin credit_d = credit_d - 'd1; end end // credit is available assign credit_available = credit_q <= (credit_i - 'd1); // a request id passed on as valid if the input is valid and we have credit. assign req_valid_o = req_valid_i & credit_available; // a request id passed on as ready if the input is ready and we have credit. assign req_ready_o = req_ready_i & credit_available; // state `FF(credit_q, credit_d, '0, clk_i, rst_ni) endmodule : stream_throttle
リクエストが転送されるとカウンタをインクリメントし、レスポンスが返るとデクリメントする。クレジットが利用可能な場合のみ、リクエストが通過する。
stream_delay.sv
ストリームに固定遅延またはランダム遅延を追加するモジュールである。 テストベンチでの動作確認やタイミング調整に使用される。
// Author: Florian Zaruba, zarubaf@iis.ee.ethz.ch // Description: Delay (or randomize) AXI-like handshaking module stream_delay #( parameter bit StallRandom = 0, parameter int FixedDelay = 1, parameter type payload_t = logic, parameter logic [15:0] Seed = '0 )( input logic clk_i, input logic rst_ni, 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 lfsr_16bit #( .WIDTH ( 16 ), .SEED ( Seed ) ) i_lfsr_16bit ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), .en_i ( load ), .refill_way_oh ( ), .refill_way_bin ( counter_load ) ); end else begin : gen_fixed_delay assign counter_load = FixedDelay; end counter #( .WIDTH ( CounterBits ) ) i_counter ( .clk_i ( clk_i ), .rst_ni ( rst_ni ), .clear_i ( 1'b0 ), .en_i ( en ), .load_i ( load ), .down_i ( 1'b1 ), .d_i ( counter_load ), .q_o ( count_out ), .overflow_o ( ) ); always_ff @(posedge clk_i or negedge rst_ni) begin if (~rst_ni) begin state_q <= Idle; end else begin state_q <= state_d; end end end endmodule
固定遅延モードでは指定されたサイクル数だけ遅延させ、ランダム遅延モードではLFSRを使用してランダムな遅延を生成する。