FPGA个人笔记

本人学习FPGA的笔记,稍作整理,将作不定时更新。希望能帮到大家,也希望大家能一起交流学习。


1.Function的使用

function中要有begin-end
Eg:fuction [7:0] test;
Input [7:0] a,b;
Output [7:0] out;
Begin
...
End


2.延迟一个时钟周期
(深入浅出玩转fpga第71页)
Input reg;
Reg regr1,regr2,regr3;
Begin
Regr1 <= reg;
Regr2 <= regr1;
Regr3 <= regr2;


Wire pos_regr1 = regr1 & ~regr2; //pos_regr2比pos_regr1延迟一个时钟周期,确保
Wire pos_regr2 = regr2 & ~regr3; //数据被稳定锁存


Pos_regr2比reg上升沿延迟一个时钟周期,pos_regr1跟reg上升沿同个周期触发


3.维持一个时钟周期
(深入浅出玩转fpga第191页)
用寄存器把值存起来,将寄存器的值跟新数据取反再按位与,非零的话说明两次数据不一样,存到一个wire型变量,这个变量将维持一个时钟周期。
Eg:input a;
Reg a_r;
Always @(posedge clk) begin
A_r <= a;
end
Wire a_ctrl = a_r & ~a;


电平触发的可以通过取反在按位与/按位或编程边沿触发。


4.模块划分的原则
(1)对每个同步时序设计的子模块的输出使用寄存器。
(2)将相关的逻辑或者可以复用的逻辑划分在同一模块内。
(3)将不同优化目标的逻辑分开。
(4)将松约束的逻辑归到同一模块。
(5)将存储逻辑独立划分成模块。
(6)合适的模块规模。


5.异或的应用
Always模块中用reg型变量记录每次采集到的数据,与前一次数据进行异或,能将乒乓开关转换成琴键开关,即电平触发的可以通过取反在按位与/按位或编程边沿触发。
Eg:input a;
Reg a_r;
Always @(posedge clk) begin
A_r <= a;
end
Wire a_ctrl = a_r ^ a;
Always块中能用寄存器存储前一个时钟的值,与当前的值进行比较处理。


6.时序逻辑要注意的问题
语句是并行执行的,如果接下来的语句要对上一条语句进行判断,是在下一次判断条件来时再判断。如果判断条件是clock,问题不大。如果判断条件是case语句或者if语句,要注意下一次能不能跳到语句中。


7.模块划分原则
一个功能一个模块


8.模块接口
采用类似C语言函数的数据传入,数据输出,以及返回值。(个人看法)


9.输出寄存器化
输出一般定义一个reg型变量,在always中赋值,再用assign将变量输出到端口。


10.存储器类型建模
Eg.定义10个数据位宽为8bit的RAM: (不是1024个8位的ram)
Reg[7:0] RAM[0:9]
在使用存储单元时,不能直接引用存储器某地址的某比特位值,下面两种描述方法都是错误的。
RAM[32][2]
RAM[32][0:7]
正确的操作方法是将存储单元赋值给某个寄存器,再对寄存器的某个比特位进行操作。
Reg[7:0] rRAM;
rRAM <= RAM[32]; //READ
RAM[32] <= rRAM[7:0]; //WRITE


11.读写FIFO
写FIFO:写信号和数据同个周期发送
读FIFO:送读信号,数据到数据线Q,数据线上的Q一直保存着上一次FIFO输出的数,上位机再读数据线Q上的值。最好是上位机发一个写指令让FIFO把数据读出来,再发一个读指令,把数据从数据线上读走。因为读FIFO有一个周期的延迟,数据线上的数据可能是错的。


12.宏定义的使用
多使用宏定义,方便修改程序。


13.参数定义
注意位数,特别是wire型,要定义,没定义默认的是1bit的。


14.参数初始化
要注意初始化,起始值不对可能会对程序造成影响


15.赋值要注意的问题
两个语句中同时对一个变量进行赋值会出错,特别是没初始化变量的时候。
Eg. 两个if中,一个对变量赋值,一个让变量保持原本的数值,如果两个条件都成立的话,变量将保持原本的数值,另一个if条件中将赋值不成功。


16.综合通过,编译没通过,报管脚不存在的原因
编译时错误如下:
Error: PDC01: port name doesn't exist in the netlist or is not connected to an IoCell macro at PDC Line : set_io TrigInput -direction Input


综合通过,编译没通过。这是因为程序中的引脚没使用,综合工具把引脚综合掉了。这是程序上的错误。解决方法:检查程序的逻辑。


遇到的问题:
SB1_RX经过SB1,传RESULT到CCU,CCU再将结果传到TXRESULT。SB1程序没问题,将RESULT传到CCU后CCU做处理,CCU程序有问题,没有将结果传到TXRESULT,也会将SB1_RX管脚综合掉。




17.驱动使用要注意的问题
驱动中对FPGA下操作指令前下个初始化的指令,防止出错。


18.SRAM使用中遇到的问题
Pdf中:


写使能信号,数据,地址同个周期给,再给读使能和地址,可以读出数据。
编程中可以把写地址先减1,然后地址,数据,写使能同时给。
读的时候不能连续读,两次读之间需要有延时。(自己测试出来的,在用户手册中没找到原因)。
Eg:
写过程:
RAM_WADDR <= 10'd1023;
        if (PC_Write && Addr == Addr_RAMScanListInput)      
        begin
            RAM_WEN     <= enable;
            RAM_WADDR   <= RAM_WADDR + 1; 
            RAM_WD      <= LD[8:0];
        End
读过程:
RAM_RADDR <= 10'd0;
RAM_RADDR <= RAM_RADDR + 1;
 {ENorNot, rScanList[7:0]}   <= RAM_RD[8:0];


19.嵌套if要主要的问题
如果嵌套几个if语句,在最外层if的else里面对变量进行赋值,防止不在条件里面时变量的值是错的。


20.Task和function使用方法
task和function可以综合。两个之间的区别:task返回的数值是通过输出端口的变量输出的。函数是通过函数本身的返回值返回的。task相当于C语言中的函数声明为void,参数列表中指针。Function相当于函数声明为int,参数列表中没有指针。(Task和function在一个时钟周期之后就返回,所以所有操作需要在一个时钟周期内完成。有误!)
Eg:
reg[7:0] aa;
reg[7:0] bb;


always @(posedge Lclk or negedge Lreset)
begin
    if(!Lreset)
    begin
        aa <= 8'd1;
        bb <= 8'd1;
    end
    else
    begin
        task1(1,2,aa);
        bb <= fun1(1);
    end
end


task task1;
<
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值