Alwaysblock1
組合邏輯always塊的使用,注意這里的wire和reg綜合出來的結果是一樣的,這里只是verilog語法導致二者宣告不一樣,
// synthesis verilog_input_version verilog_2001 module top_module( input a, input b, output wire out_assign, output reg out_alwaysblock ); assign out_assign=a&b; always@(*) begin out_alwaysblock=a&b; end endmodule
Alwaysblock2
組合邏輯用阻塞賦值,時序邏輯用非阻塞賦值,這里與verilog仿真器追蹤事件的原理有關,不遵循這一規則將導致很難發現模擬和綜合出的硬體之間的非確定性和錯誤,
module top_module( input clk, input a, input b, output wire out_assign, output reg out_always_comb, output reg out_always_ff ); assign out_assign=a^b; always@(*) begin out_always_comb=a^b; end always@(posedge clk) begin out_always_ff<=a^b; end endmodule
Always if
使用if陳述句來表示多路選擇器.
// synthesis verilog_input_version verilog_2001 module top_module( input a, input b, input sel_b1, input sel_b2, output wire out_assign, output reg out_always ); assign out_assign=(sel_b1&sel_b2)?b:a; always@(*) begin if(sel_b1&sel_b2) out_always=b; else out_always=a; end endmodule
Always if2
這一節告訴了怎么避免if陳述句綜合出不期望的Latch,即把else的情況補全,
// synthesis verilog_input_version verilog_2001 module top_module ( input cpu_overheated, output reg shut_off_computer, input arrived, input gas_tank_empty, output reg keep_driving ); // always @(*) begin if (cpu_overheated) shut_off_computer = 1; else shut_off_computer = 0; end always @(*) begin if (~arrived) keep_driving = ~gas_tank_empty; else keep_driving = 0; end endmodule
Always case
case陳述句的用法,注意case也要把所有條件覆寫,如寫一個default,避免綜合出不期望的latch,
module top_module ( input [2:0] sel, input [3:0] data0, input [3:0] data1, input [3:0] data2, input [3:0] data3, input [3:0] data4, input [3:0] data5, output reg [3:0] out );// always@(*) begin // This is a combinational circuit case(sel) 3'd0:out=data0; 3'd1:out=data1; 3'd2:out=data2; 3'd3:out=data3; 3'd4:out=data4; 3'd5:out=data5; default:out=0; endcase end endmodule
Always case2
這一題是一個優先編碼器,標準答案直接把所有情況都列出來了,我這里直接用了一個casex,即如果比較雙方有一方的某些位的值是z或x,那么這些位的比較就不予考慮,
// synthesis verilog_input_version verilog_2001 module top_module ( input [3:0] in, output reg [1:0] pos ); always@(*) begin casex(in) 4'bxxx1:pos=2'd0; 4'bxx10:pos=2'd1; 4'bx100:pos=2'd2; 4'b1000:pos=2'd3; default:pos=2'd0; endcase end endmodule
Always casez8
這題是一個八位的有限編碼器,這里教了casez的使用,和casex的使用是基本一致的,區別是case是全等比較,casez高阻態和0、1比較結果為1,與x比較結果為零,而casex中不定態與0、1、z比較結果均為1,
module top_module ( input [7:0] in, output reg [2:0] pos ); always@(*) begin casez(in) 8'bzzzz_zzz1:pos=0; 8'bzzzz_zz10:pos=1; 8'bzzzz_z100:pos=2; 8'bzzzz_1000:pos=3; 8'bzzz1_0000:pos=4; 8'bzz10_0000:pos=5; 8'bz100_0000:pos=6; 8'b1000_0000:pos=7; default:pos=0; endcase end endmodule
Always nolatches
這里又使用了另外一種方法避免latch:即在組合邏輯塊中賦初值,
// synthesis verilog_input_version verilog_2001 module top_module ( input [15:0] scancode, output reg left, output reg down, output reg right, output reg up ); always@(*) begin up = 1'b0; down = 1'b0; left = 1'b0; right = 1'b0; case (scancode) 16'he06b:left=1'b1; 16'he072:down=1'b1; 16'he074:right=1'b1; 16'he075:up=1'b1; endcase end endmodule
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/519127.html
標籤:其他
上一篇:OpenGL 反色
下一篇:JVM中的行程和執行緒
