以前经常遇见这样的事情:都是同样的逻辑“啊,为什么上次都是对的,这次就
不对了"。
现写逻辑,写完了去仿真。这个过程对我来说不仅会用很多时间,也不方便对以前的逻辑进行查漏补缺。
再一个就是写多了发现其实都是以前写过的一些逻辑的新的组合。
因为这些缘由吧,整理了这篇文章。
1. 接口类
1.1 低速接口
1.1.1 UART
标准的UART串口,我用得比较多的波特率有115200bps和9600bps,链接里面的程序,支持这两种波特率和奇偶校验。
https://download.csdn.net/download/younghuadadao/88355738
https://download.csdn.net/download/younghuadadao/88355737
1.1.2 IIC
IIC协议经常用来读温度、电压等参数。
https://download.csdn.net/download/younghuadadao/88616873
I2cBus inst_I2cBus
(
.clk (clk),
.rst_n (rst_n),
.i2c_io (SMBDAT),
.i2c_clk (SMBCLK),
.i2c_en (i2c_en),
.i2c_busy (i2c_busy),
.Ack_Addr_ok (Ack_Addr_ok),
.operate (operate),
.r_addr (r_addr),
.r_data (r_data),
.r_data_vaild (r_data_vaild)
);
1.1.3 SPI
一个比较基础的spi逻辑。
https://download.csdn.net/download/younghuadadao/88890699
spi_4_timing #(
.DATA_WIDTH(DATA_WIDTH),
.SYS_CLK_FREQ(SYS_CLK_FREQ),
.SPI_CLK_FREQ(SPI_CLK_FREQ)
) inst_spi_4_timing (
.clk_1 (clk_1),
.rst_n (rst_n),
.data_in (data_in),
.data_in_en (data_in_en),
.sclk (sclk),
.scs (scs),
.sdi (sdi),
.sdo (sdo),
.bus_busy (bus_busy),
.data_out (data_out),
.data_out_en (data_out_en)
);
1.1.4 自定义串口
可编程芯片和可编程芯片之间通信是自定的协议的,用得比较多的就是同步串口和异步串口。
1.1.4.1 同步串口
1.1.4.2 异步串口
390.625KHz的波特率,接收32位数据,发送42位数据。高位在前,低位在后。
使用16倍的时钟采样,390.625KHz*16=6.25MHz。
程序aserial_deal .v链接:
https://download.csdn.net/download/younghuadadao/88353307
aserial_deal inst_aserial_deal(
.clk6_25m (clk6_25m), //6.25MHz时钟
.rst_n (rst_n), //复位信号
.In3_sync (In3_sync), //接收数据,产生中断信号
.syncTriggerRx (syncTriggerRx), //串口接收,波特率390.625KHz
.sync_out (sync_out), //串口接收数据
.syncTriggerTx (syncTriggerTx), //串口发送,波特率390.625KHz
.d1 (d1), //串口发送数据d1
.d2 (d2),
.d3 (d3),
.d4 (d4)
);
1.2 高速接口
GTX_IP核的配置端口、数据端口,可以选择使用AXI接口,比如MIG、AURORA、JESD204B等。
1.2.1 AXI-EMC
PS和PL之间的异步寄存器接口。
https://download.csdn.net/download/younghuadadao/88355877
axi_async_decode inst_axi_async_decode
(
.reset_n (FCLK_RSTET_N),
.pl_clk (FCLK_0),
.mem_a (mem_a_0),
.mem_wen (mem_wen_0),
.mem_cen (mem_cen_0),
.mem_oen (mem_oen_0),
.mem_dq_o (mem_dq_o_0),
.mem_dq_i (mem_dq_i_0),
.clk200m (clk200m),
.BRAM_PORTB_200M_addr(BRAM_PORTB_200M_addr),
.BRAM_PORTB_200M_clk(BRAM_PORTB_200M_clk),
.BRAM_PORTB_200M_din(BRAM_PORTB_200M_din),
.BRAM_PORTB_200M_dout(BRAM_PORTB_200M_dout),
.BRAM_PORTB_200M_en(BRAM_PORTB_200M_en),
.BRAM_PORTB_200M_rst(BRAM_PORTB_200M_rst),
.BRAM_PORTB_200M_we(BRAM_PORTB_200M_we),
.clk (clk50m), //打拍时钟
.cmd_clk (cmd_clk),
.cmd_data_0 (cmd_data_0),
.cmd_data_1 (cmd_data_1),
.cmd_data_2 (cmd_data_2),
.cmd_data_3 (cmd_data_3),
.cmd_data_4 (cmd_data_4),
.cmd_data_5 (cmd_data_5),
.cmd_data_6 (cmd_data_6),
.cmd_data_7 (cmd_data_7),
.ramset_data_0 (ramset_data_0), //使用异步ram,与200M时钟同步
.ramset_data_1 (ramset_data_1),
.ramset_data_2 (ramset_data_2),
.ramset_data_3 (ramset_data_3),
.ramset_data_4 (ramset_data_4),
.ramset_data_5 (ramset_data_5),
.ramset_data_6 (ramset_data_6),
.ramset_data_7 (ramset_data_7)
);
1.2.2 AXI-DMA
PS和PL之间的数据流接口, 用接收fifo和发送fifo缓存。
https://download.csdn.net/download/younghuadadao/88355893
dma_buffer inst_dma_buffer
(
.i_clk100M (FCLK_0),
.i_rst_n (FCLK_RSTET_N),
.i_prog_empty (0),
.i_rd_en (rd_en),
.i_dout (dout),
.i_S_AXIS_S2MM_0_tready (S_AXIS_S2MM_0_tready),
.s2mm_prmry_reset_out_n_0 (s2mm_prmry_reset_out_n_0),
.s2mm_fifo0_irq_en (0),
.s2mm_fifo0_rst (s2mm_fifo0_rst),
.dma0_psread_32bit_length (8192),
.dma0_plwrite_32bit_length (8192),
.dma0_plwrite_32bit_length_delay_time (0),
.speed_test_en (vio_dma_test),
.o_In2 ( ),
.o_S_AXIS_S2MM_0_tdata (S_AXIS_S2MM_0_tdata),
.o_S_AXIS_S2MM_0_tkeep (S_AXIS_S2MM_0_tkeep),
.o_S_AXIS_S2MM_0_tlast (S_AXIS_S2MM_0_tlast),
.o_S_AXIS_S2MM_0_tvalid (S_AXIS_S2MM_0_tvalid),
.prog_full_s2mmb ( ),
.mm2s_prmry_reset_out_n_0 (mm2s_prmry_reset_out_n_0),
.M_AXIS_MM2S_0_tdata (M_AXIS_MM2S_0_tdata),
.M_AXIS_MM2S_0_tkeep (M_AXIS_MM2S_0_tkeep),
.M_AXIS_MM2S_0_tlast (M_AXIS_MM2S_0_tlast),
.M_AXIS_MM2S_0_tready (M_AXIS_MM2S_0_tready),
.M_AXIS_MM2S_0_tvalid (M_AXIS_MM2S_0_tvalid),
.mm2s_fifo_data ( ),
.mm2s_fifo_prog_empty ( ),
.mm2s_fifo_rd_en ( )
);
1.2.3 AXI-LITE
突发传输模式。
缓存fifo:https://download.csdn.net/download/younghuadadao/88364942
axi接口:https://download.csdn.net/download/younghuadadao/88364953
checkpoint inst_checkpoint
(
.clk (clk50m),
.rst_n (log_rst_n_1&axi_aresetn_ddr),
.check_en (wr_ddr_en),
.fifo_wr_en (wr_ddr_flag),
.wr_length (wr_length),
.data_in_1 ({4'h1,clk_cnt}),
.data_in_2 ({4'h2,clk_cnt}),
.data_in_3 ({4'h3,clk_cnt}),
.data_in_4 ({4'h4,clk_cnt}),
.data_in_5 ({4'h5,clk_cnt}),
.data_in_6 ({4'h6,clk_cnt}),
.data_in_7 ({4'h7,clk_cnt}),
.data_in_8 ({4'h8,clk_cnt}),
.pkg_wr_clk (axi_clk_ddr),
.pkg_wr_areq (pkg_wr_areq),
.pkg_wr_last (pkg_wr_last),
.pkg_wr_data (pkg_wr_data),
.pkg_wr_en (pkg_wr_en),
.pkg_wr_addr (pkg_wr_addr),
.pkg_wr_size (pkg_wr_size),
.upload_finish (upload_finish)
);
uiFDMA_v1 #(
.C_M_AXI_BURST_LEN(C_M_AXI_BURST_LEN),
.C_M_AXI_ID_WIDTH(C_M_AXI_ID_WIDTH),
.C_M_AXI_ID(C_M_AXI_ID),
.C_M_AXI_ADDR_WIDTH(C_M_AXI_ADDR_WIDTH),
.C_M_AXI_DATA_WIDTH(C_M_AXI_DATA_WIDTH)
) inst_uiFDMA (
.pkg_wr_areq (pkg_wr_areq),
.pkg_wr_last (pkg_wr_last),
.pkg_wr_data (pkg_wr_data),
.pkg_wr_en (pkg_wr_en),
.pkg_wr_addr (pkg_wr_addr),
.pkg_wr_size (pkg_wr_size),
.pkg_rd_areq (pkg_rd_areq),
.pkg_rd_last (pkg_rd_last),
.pkg_rd_data (pkg_rd_data),
.pkg_rd_en (pkg_rd_en),
.pkg_rd_addr (pkg_rd_addr),
.pkg_rd_size (pkg_rd_size),
.M_AXI_ACLK (axi_clk_ddr), //input wire M_AXI_ACLK,
.M_AXI_ARESETN (axi_aresetn_ddr), //input wire M_AXI_ARESETN,
.M_AXI_AWID (S01_AXI_ddr_awid), //output wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_AWID,
.M_AXI_AWADDR (S01_AXI_ddr_awaddr), //output wire [C_M_AXI_ADDR_WIDTH-1 : 0] M_AXI_AWADDR,
.M_AXI_AWLEN (S01_AXI_ddr_awlen), //output wire [7 : 0] M_AXI_AWLEN,
.M_AXI_AWSIZE (S01_AXI_ddr_awsize), //output wire [2 : 0] M_AXI_AWSIZE,
.M_AXI_AWBURST (S01_AXI_ddr_awburst), //output wire [1 : 0] M_AXI_AWBURST,
.M_AXI_AWLOCK (S01_AXI_ddr_awlock), //output wire M_AXI_AWLOCK,
.M_AXI_AWCACHE (S01_AXI_ddr_awcache), //output wire [3 : 0] M_AXI_AWCACHE,
.M_AXI_AWPROT (S01_AXI_ddr_awprot), //output wire [2 : 0] M_AXI_AWPROT,
.M_AXI_AWQOS (S01_AXI_ddr_awqos), //output wire [3 : 0]
.M_AXI_AWVALID (S01_AXI_ddr_awvalid), //output wire M_AXI_AWVALID,
.M_AXI_AWREADY (S01_AXI_ddr_awready), //input wire M_AXI_AWREADY,
.M_AXI_WDATA (S01_AXI_ddr_wdata), //output wire [C_M_AXI_DATA_WIDTH-1 : 0] M_AXI_WDATA,
.M_AXI_WSTRB (S01_AXI_ddr_wstrb), //output wire [C_M_AXI_DATA_WIDTH/8-1 : 0] M_AXI_WSTRB,
.M_AXI_WLAST (S01_AXI_ddr_wlast), //output wire M_AXI_WLAST,
.M_AXI_WVALID (S01_AXI_ddr_wvalid), //output wire M_AXI_WVALID,
.M_AXI_WREADY (S01_AXI_ddr_wready), //input wire M_AXI_WREADY,
.M_AXI_BID (S01_AXI_ddr_bid), //input wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_BID,
.M_AXI_BRESP (S01_AXI_ddr_bresp), //input wire [1 : 0] M_AXI_BRESP,
.M_AXI_BVALID (S01_AXI_ddr_bvalid), //input wire M_AXI_BVALID,
.M_AXI_BREADY (S01_AXI_ddr_bready), //output wire M_AXI_BREADY,
.M_AXI_ARID (S01_AXI_ddr_arid), //output wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_ARID,
.M_AXI_ARADDR (S01_AXI_ddr_araddr), //output wire [C_M_AXI_ADDR_WIDTH-1 : 0] M_AXI_ARADDR,
.M_AXI_ARLEN (S01_AXI_ddr_arlen), //output wire [7 : 0] M_AXI_ARLEN,
.M_AXI_ARSIZE (S01_AXI_ddr_arsize), //output wire [2 : 0] M_AXI_ARSIZE,
.M_AXI_ARBURST (S01_AXI_ddr_arburst), //output wire [1 : 0] M_AXI_ARBURST,
.M_AXI_ARLOCK (S01_AXI_ddr_arlock), //output wire M_AXI_ARLOCK,
.M_AXI_ARCACHE (S01_AXI_ddr_arcache), //output wire [3 : 0] M_AXI_ARCACHE,
.M_AXI_ARPROT (S01_AXI_ddr_arprot), //output wire [2 : 0] M_AXI_ARPROT,
.M_AXI_ARQOS (S01_AXI_ddr_arqos), //output wire [3 : 0] M_AXI_ARQOS,
.M_AXI_ARVALID (S01_AXI_ddr_arvalid), //output wire M_AXI_ARVALID,
.M_AXI_ARREADY (S01_AXI_ddr_arready), //input wire M_AXI_ARREADY,
.M_AXI_RID (S01_AXI_ddr_rid), //input wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_RID,
.M_AXI_RDATA (S01_AXI_ddr_rdata), //input wire [C_M_AXI_DATA_WIDTH-1 : 0] M_AXI_RDATA,
.M_AXI_RRESP (S01_AXI_ddr_rresp), //input wire [1 : 0] M_AXI_RRESP,
.M_AXI_RLAST (S01_AXI_ddr_rlast), //input wire M_AXI_RLAST,
.M_AXI_RVALID (S01_AXI_ddr_rvalid), //input wire M_AXI_RVALID,
.M_AXI_RREADY (S01_AXI_ddr_rready) //output wire M_AXI_RREADY
);
2.缓存
2.1 片内缓存
2.1.1 FIFO
不同时钟域FIFO的读写逻辑。
2.1.2 RAM(真双口RAM)
不同时钟域的RAM读写逻辑。
注意 !!!
axi-ram-controller的地址单位为4;
pl内部定义双口ram地址单位为1.
set_ram inst_ram (
.clka(axi_clk), // input wire clka
.wea(data_en), // input wire [0 : 0] wea
.addra(addra), // input wire [15 : 0] addra
.dina(data), // input wire [31 : 0] dina
.clkb(clkb), // input wire clkb
.addrb(addrb), // input wire [15 : 0] addrb
.doutb(doutb) // output wire [31 : 0] doutb
);
2.1.3 二维数组
定义一组寄存器,缓存数据量较小的数据。使用相同的时钟读写。
程序链接:https://download.csdn.net/download/younghuadadao/88355765
ram_interface inst_ram_interface
(
.BRAM_PORTB_0_addr (BRAM_PORTB_0_addr), //真双口ram地址
.BRAM_PORTB_0_clk (BRAM_PORTB_0_clk),
.BRAM_PORTB_0_din (BRAM_PORTB_0_din),
.BRAM_PORTB_0_dout (BRAM_PORTB_0_dout),
.BRAM_PORTB_0_en (BRAM_PORTB_0_en),
.BRAM_PORTB_0_rst (BRAM_PORTB_0_rst),
.BRAM_PORTB_0_we (BRAM_PORTB_0_we),
.sf2f_write_depth (write_depth), //写ram长度
.sf2f_read_depth (read_depth), //读ram长度
.dio_input_drdy (in_drdy), //fifo中的数据已经写入ram中
.rst_n (log_rst_n_1),
.clk (clk100m),
.clk10m (clk10m),
.send_flag (send_flag),
.x2 (din), //外部输入数据,写入fifo缓存,后写入ram中
.dout (dout), //根据send_flag输出二维数组中数据线
.start (start) //读ram数据使能,将数据写入 二维数组
);
2.2 外置缓存
2.2.1 DDR
使用MIG_IP核的AXI接口读写DDR,参考1.2.3 AXI-CONNECT
2.2.2 FLASH
用的比较多的是SPI接口读写FLASH,参考1.1.3 SPI
3.有符号数比较(signed)
3.1 限幅
3.1.1 在±error_const范围外
always@(posedge clk or negedge rst_n)
if(!rst_n) error<=0;
else begin
if ( error_r < error_const & (error_r[31]==0)) error <= 0;
else if(0-error_r < error_const & error_r[31]==1) error <= 0 - error_const;
else error<=error_r;
end
3.1.2 在±ann 的范围内
always@(posedge clk or negedge rst_n)
if(!rst_n) a<=0;
else begin
a<=a+b;
if ( a > ann & (a[47]==0)) a <= ann;
else if( 0-a > ann & a[47]==1) a <= 0 - ann;
end
4.加减法的运用
4.1 锯齿波
reg [31:0] clk_cnt_1;
always @(posedge clk or negedge rst_n)
if (!rst_n) begin
clk_cnt_1<=phase;
end else if(clk_cnt_1>=priod_cnt-1) begin
clk_cnt_1<=0;
end else begin
clk_cnt_1<=clk_cnt_1+1;
end
wire [31:0] saw_cnt_1_ini;
assign saw_cnt_1_ini=phase * Step_forward_r;
reg [31:0] saw_cnt_1;
always @(posedge clk or negedge rst_n)
if (!rst_n) begin
saw_cnt_1<=saw_cnt_1_ini;
end else if(clk_cnt_1==0)
saw_cnt_1<=0;
else begin
saw_cnt_1<=saw_cnt_1+Step_forward_r;
end
4.2 三角波
reg [31:0] clk_cnt;
always @(posedge clk or negedge rst_n)
if (!rst_n) begin
clk_cnt<=phase;
end else if(clk_cnt>=priod_cnt-1) begin
clk_cnt<=0;
end else begin
clk_cnt<=clk_cnt+1;
end
reg signed [39:0] Amplitude_cnt;
always @(posedge clk or negedge rst_n)
if (!rst_n) begin
Amplitude_cnt<=0;
end else begin
if(clk_cnt==0)
Amplitude_cnt<=0;
else begin
if(clk_cnt<priod_cnt_4) begin
Amplitude_cnt<=Amplitude_cnt+Step_forward;
end else if(clk_cnt>=priod_cnt_4 & clk_cnt<=priod_cnt_4*3) begin
Amplitude_cnt<=Amplitude_cnt-Step_forward;
end else if(clk_cnt>priod_cnt_4*3) begin
Amplitude_cnt<=Amplitude_cnt+Step_forward;
end
end
end
5.仿真
5.1 模板
`timescale 1ns/1ps
module TB();
reg clk=0;
reg rst_n;
localparam priod=5;
always #priod clk=~clk;
initial begin
glb_rst_n();
end
task glb_rst_n;
begin
rst_n=0;
repeat(100) @(posedge clk);
rst_n=1;
end
endtask : glb_rst_n
generate
if(master_en) begin
...//语句 、例化其他模块
end else begin
... //语句 、例化其他模块
end
endgenerate
genvar i;
generate
for(i=0; i<16; i=i+1) begin
IOBUF inst_iobuf (.O(a_i[i]),.I(a_o[i]),.T(a_t[i]));
end
endgenerate
endmodule
5.2 写文件
vivado将自动创建文件。
always@(posedge clk)
if(m_axis_data_tvalid) begin
file=$fopen("file_path/data.txt");
$fwrite(file,"%d\n", $signed(dout)); //保存格式为10进制有符号数
end else
$fclose(file);
5.3 读数据文件
5.3.1 *.coe
5.3.1.1 FIR滤波器系数的文件格式:
; XILINX CORE Generator(tm)Distributed Arithmetic FIR filter coefficient (.COE) File
; Generated by MATLAB(R) 9.13 and DSP System Toolbox 9.15.
; Generated on: 20-Jul-2023 10:08:02
Radix = 16;
Coefficient_Width = 16;
CoefData = ffda,
ff74,
ff84,
...
ffda;
5.3.1.2 RAM初始化的文件格式:
ram_ini.coe
MEMORY_INITIALIZATION_RADIX = 16;
MEMORY_INITIALIZATION_VECTOR =
5A,
7F,
...
00;
5.3.1 *.txt
reg[7:0] mem[1:256];
initial $readmemh("C:Desktop/mem.txt",mem); //mem.txt里的数据为十六进制
initial $readmemb("C:Desktop/mem.txt",mem); //mem.txt里的数据为二进制
6.时钟与复位
外部时钟源通过MMCM分频、倍频得出所需时钟。
根据外部硬件复位信号、内部vio复位信号和ps和时钟锁定信号生成逻辑复位。
仅供参考。
clk_rst_n inst_clk_rst_n
(
.clk (clk_in),
.pl_rst_n (pl_rst_n),
.vio_rst_n (vio_rst_n),
.clk200m (clk200m),
.clk100m (clk100m),
.clk50m (clk50m),
.clk30m (clk30m),
.clk20m (clk20m),
.clk8m (clk8m),
.clk6_25m (clk6_25m),
.log_rst_n_1 (log_rst_n_1)
);
程序clk_rst_n.v链接:
https://download.csdn.net/download/younghuadadao/88351766
时序分析参考:出现时序违例怎么解决-VIVADO
https://blog.csdn.net/younghuadadao/article/details/132537410
7.实用的条件编译命令
仿真和使用测试数据测的时候很方便。
`define test
reg [27:0] clk_cnt;
always @(posedge clk50m or negedge log_rst_n_1)
if (!log_rst_n_1) begin
clk_cnt<=0;
end else if(wr_ddr_flag) begin
clk_cnt<=clk_cnt+1;
end
`ifdef test
assign data_in_1 = clk_cnt;
`else
assign data_in_1 = sf_data ;
`endif
8.实用的parameter、localparam、define
parameter传参。
add #(
.a(200000000),
.b(200000000)
) inst_add (
.clk (clk200m),
.clk200m (clk200m),
.rst_n (rst_n),
.sum (sum)
);
parameter定义参数。
module add #(
parameter a=100_000_000,
parameter b=100_000_000
)(
input clk,
input clk200m,
input rst_n,
output sum
);
//...
endmodule
9. 原语
9.1 ug480读FPGA温度
9.2 IODELAY
200M的时钟时,CNTVALUEIN=1,延时78ps
reg out_logic_r;
reg out_logic_r1;
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin
out_logic_r<= 0;
out_logic_r1<= 0;
end else begin
out_logic_r<= out_logic;
out_logic_r1<= out_logic_r;
end
end
wire out_D,out_D_1,out_D_2;
wire [4:0] CNTVALUEIN_3;
wire [4:0] CNTVALUEIN_3_1;
wire [4:0] CNTVALUEIN_3_2;
assign CNTVALUEIN_3 =~out_logic_r1 ? DELAY_1 : 5'b00000;
assign CNTVALUEIN_3_1 =~out_logic_r1 & (iodelay_cnt>31) ? DELAY_2 : 5'b00000;
assign CNTVALUEIN_3_2 =~out_logic_r1 & (iodelay_cnt>62) ? DELAY_3 : 5'b00000;
IDELAYE2 #(
.CINVCTRL_SEL("FALSE"), // Enable dynamic clock inversion (FALSE, TRUE)
.DELAY_SRC("DATAIN"), // Delay input (IDATAIN, DATAIN)
.HIGH_PERFORMANCE_MODE("TRUE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE")
.IDELAY_TYPE("VAR_LOAD"), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
.IDELAY_VALUE(1), // Input delay tap setting (0-31)
.PIPE_SEL("FALSE"), // Select pipelined mode, FALSE, TRUE
.REFCLK_FREQUENCY(200.0), // IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0).
.SIGNAL_PATTERN("DATA") // DATA, CLOCK input signal
)
idelay_3 (
.CNTVALUEOUT( ), // 5-bit output: Counter value output
.DATAOUT(out_D), // 1-bit output: Delayed data output
.C(C), // 1-bit input: Clock input
.CE(1'b1), // 1-bit input: Active high enable increment/decrement input
.CINVCTRL(1'b0), // 1-bit input: Dynamic clock inversion input
.CNTVALUEIN(CNTVALUEIN_3), // 5-bit input: Counter value input
.DATAIN(out_logic), // 1-bit input: Internal delay data input
.IDATAIN(1'b0), // 1-bit input: Data input from the I/O
.INC(1'b0), // 1-bit input: Increment / Decrement tap delay input
.LD(1'b1), // 1-bit input: Load IDELAY_VALUE input
.LDPIPEEN(1'b0), // 1-bit input: Enable PIPELINE register to load data input
.REGRST(1'b0) // 1-bit input: Active-high reset tap-delay input
);
IDELAYE2 #(
.CINVCTRL_SEL("FALSE"), // Enable dynamic clock inversion (FALSE, TRUE)
.DELAY_SRC("DATAIN"), // Delay input (IDATAIN, DATAIN)
.HIGH_PERFORMANCE_MODE("TRUE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE")
.IDELAY_TYPE("VAR_LOAD"), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
.IDELAY_VALUE(1), // Input delay tap setting (0-31)
.PIPE_SEL("FALSE"), // Select pipelined mode, FALSE, TRUE
.REFCLK_FREQUENCY(200.0), // IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0).
.SIGNAL_PATTERN("DATA") // DATA, CLOCK input signal
)
idelay_3_1 (
.CNTVALUEOUT( ), // 5-bit output: Counter value output
.DATAOUT(out_D_1), // 1-bit output: Delayed data output
.C(C), // 1-bit input: Clock input
.CE(1'b1), // 1-bit input: Active high enable increment/decrement input
.CINVCTRL(1'b0), // 1-bit input: Dynamic clock inversion input
.CNTVALUEIN(CNTVALUEIN_3_1), // 5-bit input: Counter value input
.DATAIN(out_D), // 1-bit input: Internal delay data input
.IDATAIN(1'b0), // 1-bit input: Data input from the I/O
.INC(1'b0), // 1-bit input: Increment / Decrement tap delay input
.LD(1'b1), // 1-bit input: Load IDELAY_VALUE input
.LDPIPEEN(1'b0), // 1-bit input: Enable PIPELINE register to load data input
.REGRST(1'b0) // 1-bit input: Active-high reset tap-delay input
);
IDELAYE2 #(
.CINVCTRL_SEL("FALSE"), // Enable dynamic clock inversion (FALSE, TRUE)
.DELAY_SRC("DATAIN"), // Delay input (IDATAIN, DATAIN)
.HIGH_PERFORMANCE_MODE("TRUE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE")
.IDELAY_TYPE("VAR_LOAD"), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
.IDELAY_VALUE(1), // Input delay tap setting (0-31)
.PIPE_SEL("FALSE"), // Select pipelined mode, FALSE, TRUE
.REFCLK_FREQUENCY(200.0), // IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0).
.SIGNAL_PATTERN("DATA") // DATA, CLOCK input signal
)
idelay_3_2 (
.CNTVALUEOUT( ), // 5-bit output: Counter value output
.DATAOUT(out_D_2), // 1-bit output: Delayed data output
.C(C), // 1-bit input: Clock input
.CE(1'b1), // 1-bit input: Active high enable increment/decrement input
.CINVCTRL(1'b0), // 1-bit input: Dynamic clock inversion input
.CNTVALUEIN(CNTVALUEIN_3_2), // 5-bit input: Counter value input
.DATAIN(out_D_1), // 1-bit input: Internal delay data input
.IDATAIN(1'b0), // 1-bit input: Data input from the I/O
.INC(1'b0), // 1-bit input: Increment / Decrement tap delay input
.LD(1'b1), // 1-bit input: Load IDELAY_VALUE input
.LDPIPEEN(1'b0), // 1-bit input: Enable PIPELINE register to load data input
.REGRST(1'b0) // 1-bit input: Active-high reset tap-delay input
);
IDELAYCTRL IDELAYCTRL_inst (
.RDY(RDY), // 1-bit output: Ready output
.REFCLK(clk200m), // 1-bit input: Reference clock input
.RST(~rst_n) // 1-bit input: Active high reset input
);
assign out=out_D_2;
9.3 gt_common
10. 数学计算
10.1 ADC数据归一化
10.2 一阶RC滤波
mult_s32Xs32 u_a_1(.CLK(clk),.A(filter_a_1),.B(data_in_1),.P(a_1));
mult_s32Xs32 u_b_1(.CLK(clk),.A(filter_b_1),.B(data_in_r1),.P(b_1));
always @(posedge clk or negedge rst_n)
if (!rst_n) begin
y1<=0;
data_in_r1<=0;
end else begin
y1<= a_1 + b_1;
data_in_r1<= y1[55:24];
end
wire [31:0] fil_data_1;
assign fil_data_1=y1[55:24];
10.3 CRC计算
在线生成Verilog:Generator for CRC HDL code: https://bues.ch/cms/hacking/crcgen.html
10.4 插值
10.4.1 牛顿插值
以固定时间间隔进行插值。
https://download.csdn.net/download/younghuadadao/88364952