最近的项目逻辑资源不够,因为应用需求,要一组256个四输入的模块,后来改吧改吧,改成了一组165个6输入的模块,解决了需求问题,为什么啊,因为四输入的那个模块浪费xilinx的资源了,xilinx的LUT是六输入的,xilinx在7系列前的LUT还是五输入的,现在都变成了六输入(其实是两个五输入共享连接线)。
具体应用不说了,来看看关于LUT表这件事。
LUT表是最基本的逻辑单元,入门书籍必有的内容,基本原理这里不说了。
一般的,有SLICEM和SLICEL两种,M代表存储,L代表逻辑,好记吧。
L的功能M也能实现,M比L更复杂,所以我们直接去看SLICEM。
图上面时直接从工具里面截的,这里面包括了:
6位读地址输入(A1-A6)
8位写地址输入(WA1-WA7)
写时钟(CLK)
写使能(WEN)
数据输入(DI1)
数据输出(O6)
移位寄存器输出(MC31)
除此之外,由于DI2输入线和O5输出的存在,这片LUT还可以被配置为32-depth,2-bit-data-wide的RAM。
为什么写是8位,读是6位呢?有疑惑就看datasheet或者user guide啊,翻出UG474,里面有张图,看了就明白了:
拿一个SLICEM的四个LUT搭一个256的单口RAM,看到了吧,写地址8位直接用,读地址用6位,然后高两bit,一个给F7MUX,一个给F8MUX,相当于做了两级二选一。
还有一个重点要说的是移位寄存器,移位寄存器用的最多的地方就是做delay 了。
下面是简单的两段代码:
always @(posedge clk )begin
shift_r <= {shift_r[62:0],rxp} ;
end
always @(posedge clk )begin
txp <= shift_r[63];
end
大概的意思就是将rxp输入延迟64个时钟周期,然后输出。在很多文档里面都说过了,LUT单元是可以直接生成移位寄存器的,当然必须是SLICEM里面的LUT的,我们看看最后生成的结果是啥样的:
有点不好看啊,我俩简单解释一下:
1.红线代表LTU读地址输入,读地址代表了移位寄存器输出的位数,写31就是延迟32位,可见所有的地址都被连接在一个高电平上,5h11111=31,一般情况下,是A[5:1]表征地址,A[0]固定为高
2.青色是时钟,这对于SLICEL来说是没有的,因为有了时钟,才可能同步操作;
3.蓝色是需要移位的数据,程序里面的rxp,直接输入到了LUT-B的数据DI1口
4.黄色从LUT-B的MC31输出的结果,一个LUT可以作为32位的移位寄存器,因为需要移位64次, 所以需要两个LUT级联才能完成完整的移位结果
5.白色是最后的输出,注意是从O6输出的,即级联之后64位移位后的结果,再过一级FF之后,就是txp 。
这种写法比较简单直观,也有一些同学想要规范,那我们调用一下官方的原语试试:
SRL16E #(
.INIT(16'h0000), // Initial contents of shift register
.IS_CLK_INVERTED(1'b0) // Optional inversion for CLK
)
SRL16E_inst (
.Q(SRL10_r), // 1-bit output: SRL Data
.CE(1), // 1-bit input: Clock enable
.CLK(clk), // 1-bit input: Clock
.D(rxp ), // 1-bit input: SRL Data
// Depth Selection inputs: A0-A3 select SRL depth
.A0(0),
.A1(1),
.A2(0),
.A3(1) //0x1010= 10
);
这是一个经典的16位寄存器的小模块,看看布线后成啥样:
1.红线代表LTU读地址输入,读地址代表了移位寄存器输出,一般情况下,是A[5:1]表征地址,但是我们看到黄色线代表的数据激怒的是DI2,也就是用了两个5输入LUT中的一个,所以真实的地址是4‘h1010 = 10,也就是移位10+1次,A[0]固定为高
2.青色是时钟;
3.黄色是输入,rxp ,注意是从DI2口输入的
4.白色是最后的输出,注意是从O6输出的,即10位移位后的结果,也就是SRL10_r。
7系列因为LUT表地址位增加,因此还支持32位移位的原语,我们来看看:
SRLC32E #(
.INIT(32'h00000000), // Initial contents of shift register
.IS_CLK_INVERTED(1'b0) // Optional inversion for CLK
)
SRLC32E_inst (
.Q(SRL20_r), // 1-bit output: SRL Data
.Q31(SRL31_r), // 1-bit output: SRL Cascade Data
.A(5'd20), // 5-bit input: Selects SRL depth
.CE(1), // 1-bit input: Clock enable
.CLK(clk), // 1-bit input: Clock
.D(rxp ) // 1-bit input: SRL Data
);
看看会是怎样布线的:
1.红线代表LTU读地址输入,读地址代表了移位寄存器输出,一般情况下,是A[5:1]表征地址,是5‘h10100 = 20,也就是移位20次,A[0]固定为高
2.青色是时钟;
3.黄色是输入,rxp ,注意是从DI1口输入的
4.白色时最后的输出,注意是从O6输出的,即20+1位移位后的结果,也就是SRL20_r。
5.咖啡色是32位移位后的结果,也就是SRL31_r
这个移位跟信号实际delay的关系,还要看个仿真才能看明白:
图要放大看,rxp_r信号delay了11个时钟节拍(计数器从750到761)得到信号SRL10_r,delay了21个时钟节拍得到了信号SRL20_r,delay了32个时钟节拍得到信号SRL31_r。
也就是delay的时钟节拍N,与配置的LUT地址A之间的关系为:
N = A + 1
-
移位寄存器
+关注
关注
2文章
258浏览量
22227
原文标题:二大爷聊FPGA(8).LUT与移位寄存器
文章出处:【微信号:zhuyandz,微信公众号:FPGA之家】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论