SystemVerilog中生成0-10个随机触发器的实现问题求助
SystemVerilog随机0-10拍延迟解决方案(处理0拍直接输出的情况)
我明白你的需求了:想让数据随机延迟0到10个时钟周期,当随机数抽到0的时候,数据直接输出不用打拍,但现在这块逻辑出了问题。咱们来一步步解决它。
首先先修正你原来的随机数生成逻辑——原来的$urandom(CH_NUM)%10只能生成0-9的数,要是想覆盖0-10的范围,直接用$urandom_range(0,10)更直观准确,也不容易出错。
然后核心逻辑要区分0拍和非0拍的情况:0拍时直接把输入怼到输出,非0拍时用移位寄存器缓存数据,对应延迟周期输出。下面是完整的修正代码:
module tx_delay_bmod_1(clk, i_tx_data, o_tx_data); parameter CH_NUM = 4; input clk; input i_tx_data; output reg o_tx_data; int random_flop_cnt; // 定义移位寄存器,长度覆盖最大延迟10拍 reg [0:9] delay_buffer; initial begin // 直接生成0-10的随机延迟数,也可以结合CH_NUM做通道专属种子 random_flop_cnt = $urandom_range(0, 10); // 如果要每个通道不同随机数,改成下面这句 // random_flop_cnt = $urandom_range(0, 10, CH_NUM); end always @(posedge clk) begin // 先更新移位寄存器,把新数据移进去,旧数据往后推 delay_buffer <= {delay_buffer[1:9], i_tx_data}; // 根据随机延迟数选择输出逻辑 if (random_flop_cnt == 0) begin // 0拍延迟,直接输出当前输入 o_tx_data <= i_tx_data; end else begin // 1-10拍延迟,取缓存里对应位置的数据 // 比如延迟1拍取上一拍的数据(delay_buffer[0]),延迟10拍取10拍前的数据(delay_buffer[9]) o_tx_data <= delay_buffer[random_flop_cnt - 1]; end end endmodule
关键细节说明:
- 移位寄存器的作用:
delay_buffer每次时钟沿都会把新的输入数据移到最右侧,旧数据依次左移,这样就能缓存最近10个周期的输入数据,对应1-10拍的延迟需求。 - 0拍逻辑的处理:单独加分支判断,直接把
i_tx_data赋值给o_tx_data,完全跳过打拍流程,符合你的需求。 - 动态更新延迟数:如果需要每隔一段时间重新生成随机延迟(比如每次传输完一组数据就换延迟),可以把随机数生成逻辑放到时钟驱动的always块里,比如:
always @(posedge clk) begin static int cycle_cnt = 0; cycle_cnt <= cycle_cnt + 1; // 每100个时钟周期更新一次延迟数 if (cycle_cnt == 100) begin cycle_cnt <= 0; random_flop_cnt = $urandom_range(0, 10); end end
另外如果你的i_tx_data是多位宽总线,只需要把delay_buffer的位宽改成对应的数据位宽就行,比如8位数据就改成reg [7:0] delay_buffer[0:9];。仿真初期如果怕出现X态,可以在initial里给delay_buffer赋初始值:delay_buffer = '{default:0};
内容的提问来源于stack exchange,提问作者Lakshmana
相关产品推荐
相关产品推荐

