Files
b210-k7-fpga/lib/rfnoc/blocks/rfnoc_block_radio/sim_radio_gen.sv
T
Wade Fife 9ddb360199 fpga: rfnoc: Fix strobe probability in radio simulator
Original-commit: 8f68886ee3045abb486bfa8179e7129ebd377580
2022-03-04 18:46:12 -06:00

104 lines
3.4 KiB
Systemverilog

//
// Copyright 2022 Ettus Research, A National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: sim_radio_gen
//
// Description: Generate radio data for simulation purposes. The strobe pattern
// is random, which is not like a normal radio but covers every possibility.
// The data pattern is an incrementing sequence of samples, with each channel
// starting at a different value to differentiate them. Strobe and time are
// common between channels.
//
module sim_radio_gen #(
parameter int NSPC = 1, // Number of samples per clock cycle
parameter int SAMP_W = 32, // Length of each radio sample
parameter int NUM_CHANNELS = 1, // Number of radio RX ports
parameter int STB_PROB = 50, // Probability of STB being asserted on each clock cycle
parameter int INCREMENT = 2, // Amount by which to increment
parameter int PPS_PERIOD = 50 // Period of the PPS output
) (
input bit radio_clk,
input bit radio_rst,
output bit [NUM_CHANNELS*SAMP_W*NSPC-1:0] radio_rx_data,
output bit [ NUM_CHANNELS-1:0] radio_rx_stb,
output bit [ 63:0] radio_time,
output bit radio_pps
);
localparam int RADIO_W = SAMP_W*NSPC;
typedef bit [RADIO_W-1:0] radio_t; // Radio output word
typedef bit [SAMP_W-1:0] sample_t; // Single sample
initial assert (PPS_PERIOD % INCREMENT == 0) else
$fatal(1, "PPS_PERIOD must be a multiple of INCREMENT");
// Generate an initial value all radio channels
function radio_t [NUM_CHANNELS-1:0] radio_init();
radio_t [NUM_CHANNELS-1:0] ret_val;
for (int n = 0; n < NUM_CHANNELS; n++) begin
sample_t sample;
// Calculate the value of first sample in this radio channel
sample = sample_t'((2.0 ** SAMP_W) / NUM_CHANNELS * n);
// Calculate the value of subsequent samples in the channel
for (int s = 0; s < NSPC; s++) begin
ret_val[n][s*SAMP_W +: SAMP_W] = sample + s;
end
end
return ret_val;
endfunction : radio_init
//---------------------------------------------------------------------------
// Radio Data Generation
//---------------------------------------------------------------------------
radio_t [NUM_CHANNELS-1:0] data = radio_init();
assign radio_rx_data = data;
always @(posedge radio_clk) begin : radio_data_count_reg
if (radio_rst) begin
data <= radio_init();
radio_rx_stb <= '0;
end else begin
radio_rx_stb <= '0;
if ($urandom_range(99) < STB_PROB) begin
for (int n = 0; n < NUM_CHANNELS; n++) begin
for (int s = 0; s < NSPC; s++) begin
data[n][s*SAMP_W +: SAMP_W] <= data[n][s*SAMP_W +: SAMP_W] + NSPC;
end
end
radio_rx_stb <= '1;
end
end
end : radio_data_count_reg
//---------------------------------------------------------------------------
// Radio Time
//---------------------------------------------------------------------------
always @(posedge radio_clk) begin
if (radio_rst) begin
radio_time <= 64'b0;
radio_pps <= 1'b0;
end else begin
radio_pps <= 1'b0;
if (radio_rx_stb[0]) begin
radio_time <= radio_time + INCREMENT;
if (radio_time % PPS_PERIOD == 0 && radio_time != 0) begin
radio_pps <= 1'b1;
end
end
end
end
endmodule : sim_radio_gen