模拟波形
- FPGA中使用数字滤波器时,可通过观察模拟波形更好地查看滤波效果。可以通过ModelSim中的波形格式设置来实现更直观的波形显示。
右键波形
->Format
->Analog
- 效果
数值格式显示
- 不同的数值格式显示:
右键波形
->Radix
->Decimal
- 效果
临时设置格式
- 这个格式可在当前项目的中所有仿真中保持(不关闭窗口的每次重新仿真),不用向上面一样没测设置https://ww1.microchip.com/downloads/aemDocuments/documents/FPGA/swdocs/modelsim/modelsim_user_2024_2.pdf
设置默认值
- 编辑modelsim.ini的DefaultRadix
示例代码
verilog
/*
- 输出 是否找到同步头
- 找正峰
- 尝试找到超过正阈值的点作为潜在的正峰。
- 对每个可能的正峰,进一步检查它是否是局部最大值(通过比较接下来的12个样本),并记录峰值的位置。
- 验证正峰后的负峰 :
- 一旦找到一个正峰,检查其后大约18或24个样本处是否存在低于负阈值的负峰。
- 如果找到了符合条件的负峰,则认为找到了一个同步信号的开始,
*/
module MySyncDetect (
input wire reset,
input wire CLK_for_FIFO, // 同步FIFO控制信号
input wire [15:0] DATA_FIR_from_DFIFO, // 来自FIFO的数据流
input wire full_from_DFIFO, // FIFO满标志
input wire [11:0] usedw_from_DFIFO, // FIFO已用深度
output reg sync_detected, // 是否找到同步头
output reg[2:0] state // 状态机状态
);
parameter SYNCLEN = 64; // 同步长度参数,可以根据实际情况调整
parameter POS_THRESHOLD = 100; // 正阈值
parameter NEG_THRESHOLD = -100; // 负阈值
localparam DEPTH = 32; // 数据缓冲区深度
localparam FIND_RANGE = 20; // 数据缓冲区深度
// 状态机定义
localparam IDLE = 3'b000;
localparam FIND_PEAK = 3'b001;
localparam CHECK_NEGATIVE_PEAK = 3'b010;
localparam SYNC_FOUND = 3'b011;
// reg [2:0] state;
reg [2:0] next_state;
reg [15:0] data_buffer[0:DEPTH-1]; // 数据缓冲区
reg [4:0] buffer_index; // 缓冲区索引
reg [4:0] peak_index; // 峰值索引
reg bPeak; // 是否找到峰值
reg bFirstTag; // 第一个标签标记
integer i=0;
integer j;
integer k;
// 初始化状态
always @(posedge reset) begin
if (reset) begin
state = IDLE;
next_state = IDLE;
buffer_index = 5'b0;
end
end
// 控制信号
wire valid_data = (usedw_from_DFIFO > 0);// && !full_from_DFIFO;
wire [15:0] current_data = DATA_FIR_from_DFIFO;
// 时钟边沿触发过程
always @(posedge CLK_for_FIFO) begin
if (valid_data) begin
// 更新数据缓冲区
data_buffer[buffer_index] <= current_data;
buffer_index <= (buffer_index == DEPTH-1) ? 0 : buffer_index + 1;
end
// 状态机转换
state <= next_state;
end
// 下一状态逻辑
always @(posedge CLK_for_FIFO) begin
// next_state = state;
case (state)
IDLE: begin
if (valid_data)
next_state = FIND_PEAK;
end
FIND_PEAK: begin
// 查找正峰
if(buffer_index>= 12)begin
i = buffer_index-12;
end
else begin
i = buffer_index + DEPTH - 12;
end
if (data_buffer[i] > POS_THRESHOLD) begin
// 确认是否为局部最大值
bPeak = 1;
for (j = 1; j < 12; j = j + 1) begin
if (data_buffer[(i+j) % DEPTH] > data_buffer[i]) begin
bPeak = 0;
end
end
// 是局部最大值
if (bPeak) begin
peak_index = i;
next_state = CHECK_NEGATIVE_PEAK;
end
end
end
CHECK_NEGATIVE_PEAK: begin
// 验证正峰后的负峰
for (k = 18; k <= 24; k = k + 1) begin
if (data_buffer[(peak_index+k) % DEPTH] < NEG_THRESHOLD) begin
// 找到符合条件的负峰
next_state = SYNC_FOUND;
end
end
end
SYNC_FOUND: begin
// 已经找到同步头
next_state = IDLE;
end
endcase
end
// 输出逻辑
always @(posedge CLK_for_FIFO) begin
sync_detected <= 0;
case (state)
SYNC_FOUND: begin
sync_detected <= 1;
end
default: begin
sync_detected <= 0;
end
endcase
end
endmodule
tb
// Testbench for SyncDetect
`timescale 1ns/1ps
module MySyncDetect_tb;
// Inputs
reg CLK_for_FIFO;
reg [15:0] DATA_from_DFIFO;
reg full_from_DFIFO;
reg [11:0] usedw_from_DFIFO;
integer i;
// Output
wire sync_detected;
wire[2:0] state;
// Instantiate the Unit Under Test (UUT)
M2SyncDetect uut (
.CLK_for_FIFO(CLK_for_FIFO),
.DATA_FIR_from_DFIFO(DATA_from_DFIFO),
.full_from_DFIFO(full_from_DFIFO),
.usedw_from_DFIFO(usedw_from_DFIFO),
.sync_detected(sync_detected),
.state(state)
);
// Clock generation
initial begin
CLK_for_FIFO = 0;
forever #5 CLK_for_FIFO = ~CLK_for_FIFO; // 10 ns clock period
end
// Stimulus
initial begin
// Initialize inputs
DATA_from_DFIFO = -16'd23000;
full_from_DFIFO = 0;
usedw_from_DFIFO = 12'd0;
// Apply test cases
#100;
DATA_from_DFIFO = -16'd23000; // Example data
usedw_from_DFIFO = 12'd1;
#20;
DATA_from_DFIFO = -16'd1; // Example data
usedw_from_DFIFO = 12'd2;
#30;
DATA_from_DFIFO = 16'h1234; // Example data
usedw_from_DFIFO = 12'd3;
#50;
DATA_from_DFIFO = 16'hDEAD; // Example data
usedw_from_DFIFO = 12'd4;
// Apply test cases
#10;
for (i = 0; i < 5; i = i + 1) begin
DATA_from_DFIFO = -16'd23000 + i; // Example data with variation
full_from_DFIFO = (i % 2 == 0) ? 1 : 0;
usedw_from_DFIFO = 12'd100 + i * 10;
#20;
end
for (i = 0; i < 20; i = i + 1) begin
DATA_from_DFIFO = -16'd23000 + i*10; // Example data with variation
#20;
end
#50;
$stop; // End simulation
// Apply test cases
#100;
DATA_from_DFIFO = -16'd23000; // Example data
usedw_from_DFIFO = 12'd1;
#20;
DATA_from_DFIFO = -16'd1; // Example data
usedw_from_DFIFO = 12'd2;
#30;
DATA_from_DFIFO = 16'h1234; // Example data
usedw_from_DFIFO = 12'd3;
#50;
DATA_from_DFIFO = 16'hDEAD; // Example data
usedw_from_DFIFO = 12'd4;
// Apply test cases
#10;
for (i = 0; i < 5; i = i + 1) begin
DATA_from_DFIFO = -16'd23000 + i; // Example data with variation
full_from_DFIFO = (i % 2 == 0) ? 1 : 0;
usedw_from_DFIFO = 12'd100 + i * 10;
#20;
end
for (i = 0; i < 20; i = i + 1) begin
DATA_from_DFIFO = -16'd23000 + i*10; // Example data with variation
#20;
end
end
endmodule