Verilog 峰值检测
Verilog Peak detection
我是 Verilog 新手。我正在尝试检测 FPGA 上 ADC 输入信号的峰峰值电压。在此之前,我想测试一个简单但相似的代码,它可以找到一组 4 位并行输入的最小值和最大值。
最初我指定 pk_low
和 pk_high
作为第一个输入,根据即将到来的输入 pk_low
和 pk_high
应该改变或保持不变。但在模拟中,我看到 pk_low
值始终为 0。pk_high
和 pp_voltage
(峰峰值电压)未知(X)。
有什么问题?
module peak_voltage (clk, parallel_in, pk_high, pk_low, pp_voltage);
input clk;
input wire [3:0] parallel_in;
output reg [3:0] pk_high;
output reg [3:0] pk_low;
output wire [3:0] pp_voltage;
reg state;
parameter st0 = 'd0;
parameter st1 = 'd1;
parameter st2 = 'd2;
initial begin
state = st0;
pk_high <= parallel_in;
pk_low <= parallel_in;
end
always @ (posedge clk) begin
if (parallel_in > pk_high)begin
state = st1;
end else if (parallel_in < pk_low) begin
state = st2;
end else begin
state = st0;
end
end
always @(*) begin
case (state)
st0: begin
pk_low <= pk_low;
pk_high <= pk_high;
end
st1: begin
pk_low <= pk_low;
pk_high <= parallel_in;
end
st2: begin
pk_low <= parallel_in;
pk_high <= pk_high;
end
endcase
end
assign pp_voltage = pk_high - pk_low;
endmodule
您将其编码为状态机,您应该为您的案例选择器连续赋值。分配 3 位可能会成为一个单热向量。
您在此逻辑中有非阻塞赋值 - 您需要对组合逻辑使用阻塞。
您缺少峰值 high/low 值的任何显式存储。也许你可以推断出这种风格的一些闩锁,但你的意思不太清楚。
定义一些触发器,由 clk 计时,具有非阻塞分配。在这些每个周期中捕获更新的结果。
请记住,verilog 并行执行所有语句,您不应该考虑执行顺序。而是考虑明确捕获您的结果,并计算这些结果的 'next' 值。
您可以查看您的代码:
- 检查高位或低位更新
- 计算新值
- 捕获新值
你做错了(1),完全错过了(3)。将 (1) 和 (2) 一起编码可能有意义,但这取决于您要如何表达函数。
assign new_level = (in > level) ? in : level;
我是 Verilog 新手。我正在尝试检测 FPGA 上 ADC 输入信号的峰峰值电压。在此之前,我想测试一个简单但相似的代码,它可以找到一组 4 位并行输入的最小值和最大值。
最初我指定 pk_low
和 pk_high
作为第一个输入,根据即将到来的输入 pk_low
和 pk_high
应该改变或保持不变。但在模拟中,我看到 pk_low
值始终为 0。pk_high
和 pp_voltage
(峰峰值电压)未知(X)。
有什么问题?
module peak_voltage (clk, parallel_in, pk_high, pk_low, pp_voltage);
input clk;
input wire [3:0] parallel_in;
output reg [3:0] pk_high;
output reg [3:0] pk_low;
output wire [3:0] pp_voltage;
reg state;
parameter st0 = 'd0;
parameter st1 = 'd1;
parameter st2 = 'd2;
initial begin
state = st0;
pk_high <= parallel_in;
pk_low <= parallel_in;
end
always @ (posedge clk) begin
if (parallel_in > pk_high)begin
state = st1;
end else if (parallel_in < pk_low) begin
state = st2;
end else begin
state = st0;
end
end
always @(*) begin
case (state)
st0: begin
pk_low <= pk_low;
pk_high <= pk_high;
end
st1: begin
pk_low <= pk_low;
pk_high <= parallel_in;
end
st2: begin
pk_low <= parallel_in;
pk_high <= pk_high;
end
endcase
end
assign pp_voltage = pk_high - pk_low;
endmodule
您将其编码为状态机,您应该为您的案例选择器连续赋值。分配 3 位可能会成为一个单热向量。
您在此逻辑中有非阻塞赋值 - 您需要对组合逻辑使用阻塞。
您缺少峰值 high/low 值的任何显式存储。也许你可以推断出这种风格的一些闩锁,但你的意思不太清楚。
定义一些触发器,由 clk 计时,具有非阻塞分配。在这些每个周期中捕获更新的结果。
请记住,verilog 并行执行所有语句,您不应该考虑执行顺序。而是考虑明确捕获您的结果,并计算这些结果的 'next' 值。
您可以查看您的代码:
- 检查高位或低位更新
- 计算新值
- 捕获新值
你做错了(1),完全错过了(3)。将 (1) 和 (2) 一起编码可能有意义,但这取决于您要如何表达函数。
assign new_level = (in > level) ? in : level;