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

2015年7月3日 星期五

Verilog 複習



Reference : http://www.slideshare.net/itembedded/verilog-14596615

命名大小寫有差別, reg addreg Add不一樣

所有的關鍵字都是小寫 如module, endmodule

不可以以數字為命名的起始,23a, a24可以

用來描述位元的字母大小寫不分,4'd104'D10 相同

如果將負數assigned至一個integer numbers,則會以2次補數填入

wire還有其他的姊妹,wor(wired ourput 'OR' together),wand(wired ourput 'AND' together)

除法運算子(/)與取餘數運算子(%)沒有辦法合成

reg的值有任一為'x'的話,則結果會是'x'
4'b00x1 + 4b'001x = 4'b00xx

a === b 判斷包括'z''x'
a !== b 判斷包括'z''x'
a == b 判斷不包括'z''x'
a != b 判斷不包括'z''x'

{n{m}} => replicate value m, n times
{b,{3{c,d}}} => {b,c,d,c,d,c,d}

<cond_expr> ? <true_expr> : <false_expr>;
y= en1 ? dout1 : en2 ? dout2 : 1'b0
en11, y等於dout1,en10 en21,y等於

dout2,否則y0


initial只會執行一次,用在simulation,always則會始終循環執行.其內指定的Data type都要是reg

sequential => begin – end
sequential => fork – join
















blocking => '=', 用在combinational logic
在同一個程序裡,執行順序按照code的順序
non-blocking => '<=' , 用在sequential logic
在同一個程序裡,所有的code同時執行

casez : 'z' as dont care
casex : 'z' and 'x' as dont care

#<time><執行式>;
#15 reset = '1'

always@(posedge clk or negedge rst)
begin
        if(rst == 1'b0)
        begin
               a <= 1'b0;
        end
        else
        begin
               a <= b;
         end
end



task可以有任意數量的輸入,但只能有一個輸出,可以被調用多次,減少代碼重複
不能使用posedge,negedge,#delay
task內可以再次呼叫task,或是呼叫function
但是function 內不能呼叫task















function可以有多個輸出


$display,$strobe,$monitor 皆用在simulation時顯示文字
$display,$strobe => 每次執行時顯示一次
$monitor => 用於參數有改變時就顯示一次
%d(decimal),%c(character),%t(time),%m(hierarchy level)
$display(„show string“,a,b)
$displayb(as above but defaults to binary),displayh,displayo
…. monitor,strobe 以此類推


$time,$stime,$realtime
return the current simulation time as 64 bit integer,32 bit integer, real number

$reset => reset the simulation back to time 0
$stop => stop simulator and into command mode
$finish => exit the simulator


$scope(hierarchy_name) => set the current hierarchical scope to hierarchy_name
$showscopes(n) => lists all modules,tasks and block names in the current scope

$random => generates a random integer every time it is called.

Only for debussy
$dumpfile(„filename.vcd“)
$dumpvar(n,top) dumps all the variables in module top and n-1 levels below
$dumpon initiates the dump
$dumpoff stop dumping
$dumpall


$fopen
$fdisply
$fstrobe
$fmonitor
$fwrite


defparam 用來重新設定預設的參數,此過程叫做parameter overriding








2014年9月5日 星期五

4 Bits Pattern detector

Pattern detector

這個例子是用casez來做判斷,verilog,casez的好處就是可以不用在乎其它bit的狀態,所以拿這個來當pattern detector,但是這只能用在FPGA,不能做成ASIC,如果要做成ASIC理論上示要寫FSM,但是如果要找的pattern 很大,那真的會令人崩潰阿阿阿阿!

因為casez只有在verilog中有,所以我在寫一層top layer來包,duplicate data表式上層收集下來的資料連接而成,因為兩個連續的資料中一定會有我們要找的pattern在中間,但是這個casez我發現在duplicate_datapattern前需要都為零才能偵測到,例如pattern1101,duplicate資料需為00011010,如果是10011010則會找不到,這點我還沒想通為什麼 T_T

ps. detect_pos是用來指出偵測到的位置在哪裡,然後取後面的資料當作detected_data,當然也可以把pattern當成id之類,後面接的是資料

pattern_detector_top.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;


entity pattern_detector_top is
Port (
t_clk : in STD_LOGIC;
t_reset : in STD_LOGIC;
t_enable : in STD_LOGIC;
t_duplicate_data : in STD_LOGIC_VECTOR (7 downto 0);
t_pattern_data : out STD_LOGIC_VECTOR (3 downto 0);
t_pattern_detect : out STD_LOGIC);
end pattern_detector_top;


architecture Behavioral of pattern_detector_top is


begin


u_pattern_detector: entity work.pattern_detector PORT MAP(
clk => t_clk,
reset => t_reset,
enable => t_enable,
duplicate_data => t_duplicate_data,
pattern_data => t_pattern_data,
pattern_detect => t_pattern_detect
);
end Behavioral;


pattern_detector.v
module pattern_detector(
input wire clk,
input wire reset,
input wire enable,
input wire[7:0] duplicate_data,
output reg [3:0] pattern_data,
output reg pattern_detect);




parameter PATTERN = 4'b1101;

reg [3:0] detect_pos;

always @ (posedge clk or posedge reset)
begin
if(reset)
begin
detect_pos <= 4'h1;
pattern_detect <= 1'b0;
end
else
begin
if(!enable)
begin
detect_pos <= 4'h1;
pattern_detect <= 1'b0;
end
else if (!pattern_detect) //
begin
casez (duplicate_data)
{PATTERN, 4'b????}:
begin
detect_pos <=#1 4'h1;
pattern_detect <=#1 1'b1;
end


{1'b?, PATTERN, 3'b???}:
begin
detect_pos <=#1 4'h1 << 1;
pattern_detect <=#1 1'b1;
end


{2'b??, PATTERN, 2'b??}:
begin
detect_pos <=#1 4'h1 << 2;
pattern_detect <=#1 1'b1;
end


{3'b???, PATTERN, 1'b?}:
begin
detect_pos <=#1 4'h1 << 3;
pattern_detect <=#1 1'b1;
end
default:
begin
detect_pos <=#1 detect_pos;
pattern_detect <=#1 pattern_detect;
end
endcase
end
end
end
always @ (posedge clk or posedge reset)
begin
if(reset)
begin
pattern_data <= 4'h0;
end
else if (pattern_detect)
begin
case (1'b1)
detect_pos[0]:
pattern_data <=#1 duplicate_data[7:4];


detect_pos[1]:
pattern_data <=#1 duplicate_data[6:3];


detect_pos[2]:
pattern_data <=#1 duplicate_data[5:2];


detect_pos[3]:
pattern_data <=#1 duplicate_data[4:1];
endcase
end
end


endmodule

pattern_detector_tb.vhd
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

ENTITY pattern_detector_tb IS
END pattern_detector_tb;

ARCHITECTURE behavior OF pattern_detector_tb IS

-- Component Declaration for the Unit Under Test (UUT)

COMPONENT pattern_detector_top
PORT(
t_clk : IN std_logic;
t_reset : IN std_logic;
t_enable : IN std_logic;
t_duplicate_data : IN std_logic_vector(7 downto 0);
t_pattern_data : OUT std_logic_vector(3 downto 0);
t_pattern_detect : OUT std_logic
);
END COMPONENT;



--Inputs
signal t_clk : std_logic := '0';
signal t_reset : std_logic := '0';
signal t_enable : std_logic := '0';
signal t_duplicate_data : std_logic_vector(7 downto 0) := (others => '0');


--Outputs
signal t_pattern_data : std_logic_vector(3 downto 0);
signal t_pattern_detect : std_logic;


-- Clock period definitions
constant t_clk_period : time := 10 ns;

BEGIN

-- Instantiate the Unit Under Test (UUT)
uut: pattern_detector_top PORT MAP (
t_clk => t_clk,
t_reset => t_reset,
t_enable => t_enable,
t_duplicate_data => t_duplicate_data,
t_pattern_data => t_pattern_data,
t_pattern_detect => t_pattern_detect
);


-- Clock process definitions
t_clk_process :process
begin
t_clk <= '0';
wait for t_clk_period/2;
t_clk <= '1';
wait for t_clk_period/2;
end process;



-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
wait for 3 us;
t_reset <= '1';
wait for 30 ns;
t_reset <= '0';
wait for 3 us;
wait for 22 ns;
t_duplicate_data <= "00000000";
wait for 5 us;
t_enable <= '1';
t_duplicate_data <= "00011011";
wait for 32 ns;
t_duplicate_data <= "10111011";



wait;
end process;


END;


Waveform


2014年7月21日 星期一

Verilog-VHDL Coding Style for synthesis

之前讀過一篇關於這方面的文章,後來整個忘了
但是大部分的規則都還記得,關於latch或是conbinational loop
今天剛好又看到這篇,趕快來複習一下兼做筆記
Reference : RTL Coding Styles That Yield Simulation and Synthesis Mismatches.

如果違反下列的design rule會造成pre-post synthesis mismatch

Sensitivity List
其不包括關鍵字rising_edge,falling_edge,如果在sensitivity list中有多餘的無關係訊號,只會使pre-synthesis跑得更久
  1. 不完全的sensitivity list
  2. 完全的sensitivity list但是錯誤的順序,因為在pre-synthesis是順序式的執行,assign的直要先放入sensitivity list

Function
function總是被當成conbinational logic來和成,有些工程師喜歡把combinational logic寫成function,但是如果在function裡面有個latch,合成的工具沒有辦法檢查到這個錯誤,pre-synthesis會去檢查functionality,post-synthesis會檢查combinational logic,這樣就會造成pre-post synthesis mismatch

Case Statement
Full Case – 只有Verilog,VHDL不需要,因為VHDLcase others,不會有不完全的case
如果我們使用 // synopsys full_case 這個指令, 這用來指示所有的Case狀態已經被指定,如果沒有被指定的Case則自動設為dont cares,如果在case中有寫default,系統就會自動忽略這個指令,很多程式設計師喜歡用這個指令因為它可以讓設計更小而且速度更快且可以修掉latch,但是事實上不一定,它可能會對設計完全不產生影響且會使設計變大或是變慢,或是造成pre-post synthesis mismatch,下面的例子有加了指令但是還是造成的Latch



但是如果在case前先把輸出值初始化就可以避免latch的產生



Parallel Case - 只有Verilog,因為VHDL不允許overlapp 或是不完全的case
如果case中會有重複的情況,表示這個設計不是parallel,如下例3'b011,3'b101,3'b110,3'b111都有兩個以上的case符合情況,它就會依照編碼的優先順序來輸出,稱為priority encoder,irq[2]>irq[1]>irq[0],synthesis的結果parallel會是no



在下例中,不會有case重複的情形,synthesis的結果parallel會是auto



如果使用者使用 parallel_case這個指令,synthesis的結果parallel會是user
如果在overlapp的電路上使用parallel_case,會造成pre-post synthesis mismatch
如果在已經平行的電路上使用parallel_case,系統會自動忽略,不會有差別





Casex- 只有Verilog,“?,z,x“皆為dont care,VHDL不允許

case中不要使用casex,它是用來表達其它不指定的狀態,但是容易使訊號進入未知的狀態,最好用casez


Casez- 只有Verilog,“?,z“皆為dont care,VHDL不允許
雖然casezcasex功能相似,但是如果設計有問題在驗證時容易被發現,casez常用在modeling address decoders and priority encoders.但是需要小心使用,它可能也會造成三態或是浮動的訊號


------------------------------------------------- 補充----------------------------------------------------------

---------------------------------------------------------------------------------------------------------------

初始化值不要設為X
Verilog,所有被設為x的值都會被合成優化為dont care,下面的例子如果為2'b11則會造成pre-post synthesis mismatch



模型初始化使用translate_off,translate_on
不應該在初始化的時候對synthesis隱藏初始值. 這可能會造成ASIC之後初始化出現問題



translate_off,translate_on的普遍使用方法
這個指令最好是用在display information,如果用來控制functionality則非常危險,唯一例外只有在使用非同步的D flip-flopresetset,我們會需要使用這個指令來測試不同狀況的組合輸出,(This exception requires the use of non-synthesizable constructs to provide the correct presynthesis model that accurately models and matches the post-synthesis model. This exception
condition is created as follows: assert reset, assert set, remove reset, leaving set still asserted. In
this case, the D flip-flop model needs a little assistance to correctly model the set condition
during pre-synthesis simulation.)因此在設計上最好避免使用reset/setD flip-flop,在下面的例子a在模擬的時候99%正確,但是會有個缺陷,c則是100%正確




xilinxconstraint中可以用三種關鍵字來表示
Translate Off and Translate On can be used with the following words:
• synthesis
• synopsys
• pragma


Translate Off and Translate On VHDL Syntax Example
In VHDL, write Translate Off and Translate On as follows:
-- synthesis translate_off
...code not synthesized...
-- synthesis translate_on



總結
但是如果使用者需要設計priority encoder,最好使用if-else-if
在設計中不要使用full_caseparallel_case,當它們有效的時候才是最危險的! 只有在onehot FSM中可以拿優化設計
如果要設計一個dont carecase,最好使用casez,而且最好使用? 不要使用z
檢查所有的case synthesis report




Timing Delays
如果在assign的左邊放入timing delay的值,因為輸出不會因為輸入變動及時改變,造成設計不精準,其會造成pre-post synthesis mismatch


延伸閱讀補充
http://www.nspark.org.tw/webfiles/verilog_coding_style-final.pdf
verilog,組合邏輯用blocking assignment(=),循序邏輯用nonblocking assignment(<=), 如果在循序邏輯中改用blocking assignment,和成後的結果相同,但是如果程式的順序不同,則造成在程式中指定的順序會影響和成出來的結果,不要在同一個always裡面同時使用blocking assignmentnonblocking assignment


ISE的設定中可以幫Case手動設定full or parallel