单片机传给CPLD 一个16位的数据
本帖最后由 fpgaw 于 2010-7-16 10:57 编辑单片机传给CPLD 一个16位的数据,这个数据指示了热线阵( 共488个点)那一点该发热
所以我需要做一个16--488的译码器,但是我发现要用VHDL 实现这个功能,用Case语句的话
要写488条,实在是太多了,想请问个位有没有什么好的办法? assign sel_1 = (data == 16'd1);<br>
...<br>
...<br>
assign sel_488 = (data == 16'd488); 16-488之间的译码有没有规律<br>
如果有规律就可以写个小程序让给你生成你所要的VHDL代码 module example(a,b,c);<br>
input a;<br>
input b;<br>
output c;<br>
reg c; <br>
integer k;<br>
always@(a)<br>
for(k=0;k<488;k=k+1)<br>
begin<br>
if(a ==k)<br>
c=1'b1 ;<br>
else<br>
c=1'b0 ;<br>
end <br>
<br>
endmodule<br>
<br>
[ 本帖最后由 encrypt 于 2006-6-5 14:37 编辑 ] 那么大的mux,如果时间不太紧的话,搞两级译码比较好吧 3楼的方案综合器把for当成if把所有可能都综合起来,资源消耗太大了,我的意见是用4个4输入了lut,组成流水线设计,每一级译码4位,<br>
a1a2a3a4b1b2b3b4c1c2c3c4d1d2d3d4,<br>
因为只译码到488,故高7位都是0,可以至少省一个lut,<br>
b1b2b3b4只有0000,0001两种可能,分别对应0和256,比较好操作,<br>
低八位同样分c1c2c3c4和d1d2d3d4译码,分别对应(0,16,32,48,64,80,96……256共16个值)和(0~15共16个值),再把译码的值加起来,假如等于x,那么out就是发光的点,这样你的译码case或者if语句就只要写16×2+2个,少很多了。<br>
希望后面的高人还有更好的解决方法 昨天有点事没上来,今天一上来就看到了各位的见解,非常感谢各位的指教!<br>
guzhu-2000 你的方法我感觉很好,非常感谢!!<br>
以后还请各位多多指教
http://bbs.vibesic.com/images/smilies/default/smile.gif 既然是点阵就不应该是488条腿,至少应该有行和列。何况CPLD也不会给你488条腿用。<br>
比如选择22×23 = 506。23行22列。<br>
行数等于二进制数除以22,列数就等于余数。 KILLONE 说的的确有道理,把和直接相加的话,其实还是用很多小的lut级联成一个大的lut进行和的查找,这点由于自己水平有限,当时没有考虑到,考虑如下方式不知可否实现(只是想法,自己没有做过):把点阵分成上下两个部分,每部分16×16=256个点,还是用b4c1c2c3c4d1d2d3d4,b4译码成0.1两种状态,作为上下部分的使能选择,c1c2c3c4和d1d2d3d4分别译码成0~15,组成16×16的矩阵,进行选择,用32跟wire,两根线相与就是要发光的点,如下图:<br>
<br>
c1c2c3c4译码成16列<br>
d1 xxxx……………………xxxx<br>
d2 . .<br>
d3 . . 上半区(b4=0)<br>
d4 . .<br>
译码成 xxxx……………………xxxx<br>
16行<br>
--------------------------------------------------<br>
结构同上<br>
xxxx……………………xxxx<br>
. .<br>
. . 下半区(b4=1)<br>
. .<br>
xxxx……………………xxxx 原帖由 KILLONE 于 2006-6-6 14:53 发表<br>
guzhu-2000 我试了一下,发现你的方法资源和encrypt是一样多的!<br>
1 这个程序你可以写成<br>
process(a)<br>
begin<br>
b<=(others=>'0');<br>
b(conv_integer(a))<='1';<br>
end process;<br>
<br>
2 encrypt的写法<br>
... 如果你中间打一拍,timing会好很多。
页:
[1]
2