[問題] verilog 合成問題

看板Electronics作者 (EEcheng)時間4年前 (2020/04/03 01:33), 4年前編輯推噓12(12020)
留言32則, 9人參與, 4年前最新討論串1/1
各位前輩好,雖然我已經寫了 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://www.ptt.cc/bbs/Electronics/M.1585848827.A.307.html

04/03 01:35, 4年前 , 1F

04/03 01:35, 4年前 , 2F

04/03 01:36, 4年前 , 3F
※ 編輯: eecheng87 (218.164.116.170 臺灣), 04/03/2020 01:36:23 ※ 編輯: eecheng87 (218.164.116.170 臺灣), 04/03/2020 01:37:06

04/03 03:00, 4年前 , 4F
你寫的不是RTL,合成是合不出initial的
04/03 03:00, 4F

04/03 08:04, 4年前 , 5F
1.initial是不可合成的. 2.always寫combination logic時i
04/03 08:04, 5F

04/03 08:04, 4年前 , 6F
nput沒寫在sensitive list裡就會合出latch。 3.這個電路
04/03 08:04, 6F

04/03 08:04, 4年前 , 7F
沒看到clk,看來是純組合邏輯組成的,又有timing loop,
04/03 08:04, 7F

04/03 08:04, 4年前 , 8F
就算真合的出來了應該也會跑錯吧。
04/03 08:04, 8F

04/03 09:12, 4年前 , 9F
rtl code 如果沒有送 reset 訊號進來,那有辦法初始化
04/03 09:12, 9F

04/03 09:12, 4年前 , 10F
嗎?
04/03 09:12, 10F

04/03 09:14, 4年前 , 11F
另外一個問題是,組合電路沒辦法寫成 timing loop 嗎?
04/03 09:14, 11F

04/03 09:14, 4年前 , 12F
只能老實的把所有狀況寫出來?
04/03 09:14, 12F

04/03 09:30, 4年前 , 13F
1. 組合電路不需要reset 2. 不能有timing loop
04/03 09:30, 13F

04/03 09:31, 4年前 , 14F
像是你res1 = ~res1就是loop了
04/03 09:31, 14F

04/03 09:31, 4年前 , 15F
sensitive list想偷懶的話寫*比較不會出錯
04/03 09:31, 15F

04/03 09:34, 4年前 , 16F
在組合電路的if和case務必要寫滿
04/03 09:34, 16F

04/03 10:45, 4年前 , 17F
這種問題google就有了,先學會google吧..
04/03 10:45, 17F

04/03 10:47, 4年前 , 18F
智商不夠的,建立先看別人怎麼寫code,不然容易走歪..
04/03 10:47, 18F

04/03 11:02, 4年前 , 19F
有建議的地方可以看別人的code嗎?
04/03 11:02, 19F

04/03 11:06, 4年前 , 20F
google verilog 除法器............................
04/03 11:06, 20F

04/03 22:07, 4年前 , 21F
組合邏輯沒有reset,你能想像的出來inverter的reset是什
04/03 22:07, 21F

04/03 22:07, 4年前 , 22F
麼嗎?而timing loop正常情況下是不應該存在的東西,比如
04/03 22:07, 22F

04/03 22:07, 4年前 , 23F
你把一個inverter的輸出接到它自己的輸入,這就是一條tim
04/03 22:07, 23F

04/03 22:07, 4年前 , 24F
ing loop,這時你畫的出這個inverter的波形嗎?
04/03 22:07, 24F

04/07 00:20, 4年前 , 25F
寫的時候可以想像對應的電路大概長怎樣
04/07 00:20, 25F

04/09 16:12, 4年前 , 26F
我看不出來這有寫幾個學期的水平... 老師是不是教得怪怪
04/09 16:12, 26F

04/09 16:12, 4年前 , 27F
? 大一邏輯設計就會說initial不能用在RTL裡了,只是不
04/09 16:12, 27F

04/09 16:12, 4年前 , 28F
會解釋原因
04/09 16:12, 28F

04/09 16:12, 4年前 , 29F
手邊有verilog manual的話先k一下再開打吧 ,不然synthe
04/09 16:12, 29F

04/09 16:12, 4年前 , 30F
sis會warning吃到飽
04/09 16:12, 30F

04/11 01:20, 4年前 , 31F
看到initial就看不下去了
04/11 01:20, 31F

04/11 10:31, 4年前 , 32F
先把數學式寫出來 再用verilog實作數學式
04/11 10:31, 32F
文章代碼(AID): #1UXY7xC7 (Electronics)