作者eecheng87 (EEcheng)
看板Electronics
标题[问题] verilog 合成问题
时间Fri Apr 3 01:33:43 2020
各位前辈好,虽然我已经写了 verilog 几个学期了,但是以前都是用 modelsim 跑测资
档。殊不知,这学期开始要用 quartus ii 合成,才发现原来我一直都是带着错误观念写
错的程式。
目前我遇到的问题是,在 modelsim 能编译过,而且测资档也能过。拿到 quartus 合成
的时候,也成功,但是喷一堆警告。然後如果不理会警告,把生成的 .vo 和 .sdo 再那
去 modelsim 跑测资发现输出都是 xxxxxx。所以我想应该是合成出错的东西了。
希望各位前辈如果有空的话,稍微帮我看一下我的 verilog 哪里有严重的疏失。以下是
8 bit 的无号除法器,用组合电路写的。(附上排版比较好的连结
https://ideone.com/PITrCL)
程式码:
`timescale 1ns / 10ps
module div(out, in1, in2, dbz); parameter width = 8;
input [width-1:0] in1; // Dividend
input [width-1:0] in2; // Divisor
output reg [width-1:0] out; // Quotient
output reg dbz;
reg [3:0] it;
reg [width * 2 - 1:0] dividen;
reg [width * 2 - 1:0] diviser[8:0];
reg [width - 1:0] q;
reg res1, res2, res3;
initial begin
res1 = 0;
res2 = 0;
res3 = 0;
it = 0;
end always@(in1 or in2)begin
if(!{in2,{width{1'b0}}})begin
dbz = 1;
end else if(!{{width{1'b0}},in1}) begin
dbz = 0;
end else begin
dbz = 0;
res1 = ~res1;
end
end
always@(res3 or res1)begin
if(it == 0)begin
diviser[0] = {in2,{width{1'b0}}};
dividen = {{width{1'b0}},in1};
end else begin
diviser[0] = diviser[0];
dividen = dividen;
end if(it < 9)begin
if(!dividen && !it)begin
out = 0;
end else if(dividen >= diviser[it])begin
dividen = dividen - diviser[it];
q[width - it] = 1;
diviser[it + 1] = diviser[it]>>1;
res2 = ~res2;
end else begin q[width - it] = 0;
diviser[it + 1] = diviser[it]>>1;
res2 = ~res2;
end end else begin out = q;
res2 = ~res2;
end
end
always@(res2)begin
#1 if(it==9)begin it = 0;
res3 = res3;
end else begin
it = it + 1'b1;
res3 = ~res3;
end end endmodule
演算法主要是除数和被除数相比,来决定商是0或1,每次商左移一格,除数右移一格。It
纪录移动的次数,最多八次。
稍後我在留言附上我在 quartus 合成的警告,我有查过相似的状况,但改了之後警告都
没少。
我尝试过的改动:
1. if else 没写满,可能产生 latch
2. if 出现的变数在 else 也要出现
现在这里谢谢各位的帮忙。
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 218.164.116.170 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Electronics/M.1585848827.A.307.html
※ 编辑: eecheng87 (218.164.116.170 台湾), 04/03/2020 01:36:23
※ 编辑: eecheng87 (218.164.116.170 台湾), 04/03/2020 01:37:06
4F:推 zace15: 你写的不是RTL,合成是合不出initial的 04/03 03:00
5F:推 bakerly: 1.initial是不可合成的. 2.always写combination logic时i 04/03 08:04
6F:→ bakerly: nput没写在sensitive list里就会合出latch。 3.这个电路 04/03 08:04
7F:→ bakerly: 没看到clk,看来是纯组合逻辑组成的,又有timing loop, 04/03 08:04
8F:→ bakerly: 就算真合的出来了应该也会跑错吧。 04/03 08:04
9F:→ eecheng87: rtl code 如果没有送 reset 讯号进来,那有办法初始化 04/03 09:12
10F:→ eecheng87: 吗? 04/03 09:12
11F:→ eecheng87: 另外一个问题是,组合电路没办法写成 timing loop 吗? 04/03 09:14
12F:→ eecheng87: 只能老实的把所有状况写出来? 04/03 09:14
13F:推 r901042004: 1. 组合电路不需要reset 2. 不能有timing loop 04/03 09:30
14F:→ r901042004: 像是你res1 = ~res1就是loop了 04/03 09:31
15F:→ r901042004: sensitive list想偷懒的话写*比较不会出错 04/03 09:31
16F:推 r901042004: 在组合电路的if和case务必要写满 04/03 09:34
17F:推 tkhan: 这种问题google就有了,先学会google吧.. 04/03 10:45
18F:推 tkhan: 智商不够的,建立先看别人怎麽写code,不然容易走歪.. 04/03 10:47
19F:→ eecheng87: 有建议的地方可以看别人的code吗? 04/03 11:02
20F:推 tkhan: google verilog 除法器............................ 04/03 11:06
21F:推 bakerly: 组合逻辑没有reset,你能想像的出来inverter的reset是什 04/03 22:07
22F:→ bakerly: 麽吗?而timing loop正常情况下是不应该存在的东西,比如 04/03 22:07
23F:→ bakerly: 你把一个inverter的输出接到它自己的输入,这就是一条tim 04/03 22:07
24F:→ bakerly: ing loop,这时你画的出这个inverter的波形吗? 04/03 22:07
25F:推 arron860306: 写的时候可以想像对应的电路大概长怎样 04/07 00:20
26F:推 cyl61123: 我看不出来这有写几个学期的水平... 老师是不是教得怪怪 04/09 16:12
27F:→ cyl61123: ? 大一逻辑设计就会说initial不能用在RTL里了,只是不 04/09 16:12
28F:→ cyl61123: 会解释原因 04/09 16:12
29F:→ cyl61123: 手边有verilog manual的话先k一下再开打吧 ,不然synthe 04/09 16:12
30F:→ cyl61123: sis会warning吃到饱 04/09 16:12
31F:推 johnpisces2: 看到initial就看不下去了 04/11 01:20
32F:推 exezx: 先把数学式写出来 再用verilog实作数学式 04/11 10:31