顯示具有 Verilog 標籤的文章。 顯示所有文章
顯示具有 Verilog 標籤的文章。 顯示所有文章

2009年8月17日 星期一

Verilog筆記...

記錄...
一些關於Verilog撰寫方面的筆記...

1. TestBench的module宣告不用宣告input port和output ports
ex:
電路設計檔的module宣告:
test.v
----------
module test (in1, in2, out); <= 有宣告所需的input和output ports
其TestBench檔的module宣告:
test_tb.v
----------
module test_tb; <= 不需要宣告test.v中所需的input和output ports

2. TestBench通常input ports會改宣告成reg型態 / output ports會改宣告成wire型態
ex:
電路設計檔的input / output ports宣告:
test.v
----------
module test (i0, i1, i2, out);
input i0, i1, i2;
output out;
reg out;

其TestBench檔的input / output ports宣告:
test_tb.v
----------
module test_tb;
reg i0, i1, i2; <= input ports改宣告成reg型態
wire out; <= output ports改宣告成wire型態

3. 這是發生在撰寫4 Bits Up-Down Counter時發生的邏輯錯誤:

4 Bits Up-Down Counter電路設計檔:
Four_Bits_Up_Down_Counter.v
----------
// 4 Bits Up-Down Counter with reset and control signal
module Four_Bits_Up_Down_Counter (control, reset, clk, out);
input control, reset, clk;
output [3:0] out;
reg [3:0] out;

always @(posedge clk)
begin
if (~reset) // When reset = 0: zero the value of out
begin
out <= 4'b0;
end
else if (control) // If control = 1: Up-count the number
begin
// Only Up-count while the number not reach 4'b1111
if (out != 4'b1111)
begin
out <= out + 1;
end
end
else // Else if control = 0: Down-count the number
begin
// Only Down-count while the number not reach 4'b0000
if (out != 4'b0000)
begin
out <= out - 1;
end
end
end
endmodule

其TestBench檔:
Four_Bits_Up_Down_Counter_tb.v
----------
// 4 Bits Up-Down Counter with reset and control signal Test Bench
module Four_Bits_Up_Down_Counter_tb;
reg control, reset, clk;
wire [3:0] out;

Four_Bits_Up_Down_Counter tb (.control(control), .reset(reset), .clk(clk), .out(out));

initial
begin
control = 1'b1;
reset = 1'b0;
clk = 1'b0;
#10 reset = 1'b1;
#500 $finish;
end

always
begin
#10 clk = !clk;
end
endmodule

其模擬出來的out都會是Unknown的訊號:


其原因在於...
當clk由負緣拉為正緣時:
always @(posedge clk)

程式才會進入下面的if / else判斷式

但由於在clk由負緣拉為正緣前:
always
begin
#10 clk = !clk;
end

reset就已經由0改設成為1了:
#5 reset = 1'b1;

也因此導致out沒有初始值 = Unknow
如此之後不論判斷式再怎麼加 / 減
其值均會為Unknown,導致錯誤的結果


解決方法:
將進入判斷式的條件多加:always @(posedge clk or negedge reset)
將reset也加入進入判斷式的條件中...
如此當reset由正緣拉為負緣時
就會一併將out初始為0000了


原本一直以為是自己Verilog有寫錯...
在問過學長後才發現原來有這麼一個隱藏的問題!!
果然有經驗的一看到就可以很快的發現問題出在哪...

2009年5月30日 星期六

wire v.s. reg...

記錄...
轉載自網路:

簡單來說硬體描述語言有兩種用途:1. 仿真,2. 綜合
對於wirereg,也要從這兩個角度來考慮:
--------------------------------------------------------------------------------------------

仿真的角度來說,HDL語言面對的是編譯器 (如Modelsim等),相當於軟體思路
這時:
wire對應於連續賦值,如assign
reg對應於過程賦值,如always、initial
--------------------------------------------------------------------------------------------

綜合的角度來說,HDL語言面對的是綜合器 (如DC等),要從電路的角度來考慮。
這時:
1. wire變數綜合出來一般是一根導線
2. reg變數在always區塊中有兩種情況:
(1). always後是 (a or b or c) 型式的,也就是不帶Clock Edge
綜合出來還是組合邏輯電路 (Combinational Logic)
(2). always後是 (posedge clk) 型式的,也就是帶Clock Edge
綜合出來一般是循序邏輯電路 (Sequential Logic),會包含觸發器 (Flip-Flop)

在設計中:
1. 輸入信號一般來說你是不知道上一級是暫存器輸出還是組合邏輯輸出
=> 那麼對於本級來說就是一根導線,也就是wire型
2. 而輸出信號則由你自己來決定是組合邏輯輸出還是暫存器輸出
=> wire型reg型都可以
3. 但一般的,整個設計的外部輸出 (即最頂層module的輸出),要求是暫存器輸出
=> 也就是reg型,較穩定、扇出能力也較好

以上轉載自
--------------------------------------------------------------------------------------------

大體上來說wirereg都類似於C/C++的變數

但若此變數要放在:
begin...end內
,該變數須使用reg
begin...end外,則該變數須使用wire

另外使用wire時,須搭配assignreg不必

inputouputinout預設值都是wire

wirereg用錯地方,compiler都會提醒,所以不必太擔心

一個很重要的觀念:
在Verilog中使用reg,並不表示合成後就是暫存器(register)
1. 若在組合邏輯電路 (Combinational Logic)中使用reg,合成後仍只是net
2. 在循序邏輯電路 (Sequential Logic)中使用reg,合成後才會以flip-flop型式表示成暫存器(register)

以上轉載自