Verilog实现频率计数器时多驱动网络报错问题咨询
错误原因
reg类型变量在Verilog语法中不允许在多个always块中被赋值,你原有代码中内部计数寄存器count同时在时钟沿触发的计数逻辑、复位下降沿触发的清零逻辑两个always块中被赋值,因此触发多驱动网络的编译报错。- 原有代码使用阻塞赋值
=编写时序逻辑,也不符合FPGA时序逻辑的编码规范,容易引入功能异常。
修改思路
将所有时序逻辑合并到同一个时钟沿触发的always块中,通过对复位信号打拍检测上升沿、下降沿,匹配你的功能需求:
- 内部寄存器累计时钟输入脉冲数
- 复位脉冲上升沿到来时,锁存当前计数值到输出端口保持
- 复位脉冲下降沿到来时,清零内部计数寄存器重新开始计数
修正后可编译代码
module counter( input rst, input clk, output [31:0] countout ); reg [31:0] countout = 32'd0; reg [31:0] count = 32'd0; reg rst_d1; // 复位信号打一拍,用于边沿检测 // 打拍逻辑 always @(posedge clk) begin rst_d1 <= rst; end // 计数、锁存、清零逻辑,全部整合到同一个always块 always @(posedge clk) begin // 检测复位上升沿,锁存计数到输出 if(rst == 1'b1 && rst_d1 == 1'b0) begin countout <= count; end // 检测复位下降沿,清零内部计数 else if(rst == 1'b0 && rst_d1 == 1'b1) begin count <= 32'd0; end // 正常计数 else if(rst == 1'b0) begin count <= count + 1'b1; end // 复位高电平期间,内部计数保持,不做累加 end endmodule
功能说明
- 复位信号为低电平时,内部
count寄存器每个时钟上升沿累加1,正常统计输入脉冲个数 - 复位信号拉高(上升沿)的第一个时钟沿,将当前
count的数值锁存到countout端口,countout会保持该数值直到下一次复位上升沿到来 - 复位信号拉低(下降沿)的第一个时钟沿,清空内部
count寄存器,重新开始计数 - 复位高电平期间内部计数保持不变,不会出现计数溢出问题
内容的提问来源于stack exchange,提问作者tarik
相关产品推荐
相关产品推荐

