目前的兩種用法:
always @(*)
always @(posedge clk)
Build an XOR gate three ways, using an assign statement, a combinational always block, and a clocked always block. Note that the clocked always block produces a different circuit from the other two: There is a flip-flop so the output is delayed.
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 @(*) out_always_comb = a^b;
always @(posedge clk) out_always_ff <= a^b;
endmodule
case語句:
其語句結構為:
case(使用變量)
1'b0: out = 0;
endcase
注意:
case語句不用寫switch
case每一項對應的語句只有一條語句,若出現多條語句時要使用begin...end結構
case可以出現多個相同的項,但是只有第一條有用。
case對應練習題:
題目:
Case statements are more convenient than if statements if there are a large number of cases. So, in this exercise, create a 6-to-1 multiplexer. When sel is between 0 and 5, choose the corresponding data input. Otherwise, output 0. The data inputs and outputs are all 4 bits wide.
答案:
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'b000: out = data0;
3'b001: out = data1;
3'b010: out = data2;
3'b011: out = data3;
3'b100: out = data4;
3'b101: out = data5;
default:out = 3'b000;
endcase
end
endmodule
題目:
A priority encoder is a combinational circuit that, when given an input bit vector, outputs the position of the first 1 bit in the vector. For example, a 8-bit priority encoder given the input 8'b10010000 would output 3'd4, because bit[4] is first bit that is high.
Build a 4-bit priority encoder. For this problem, if none of the input bits are high (i.e., input is zero), output zero. Note that a 4-bit number has 16 possible combinations.
標准答案:
1 module top_module ( 2 input [3:0] in, 3 output reg [1:0] pos 4 ); 5 6 always @(*) begin // Combinational always block 7 case (in) 8 4'h0: pos = 2'h0; // I like hexadecimal because it saves typing. 9 4'h1: pos = 2'h0; 10 4'h2: pos = 2'h1; 11 4'h3: pos = 2'h0; 12 4'h4: pos = 2'h2; 13 4'h5: pos = 2'h0; 14 4'h6: pos = 2'h1; 15 4'h7: pos = 2'h0; 16 4'h8: pos = 2'h3; 17 4'h9: pos = 2'h0; 18 4'ha: pos = 2'h1; 19 4'hb: pos = 2'h0; 20 4'hc: pos = 2'h2; 21 4'hd: pos = 2'h0; 22 4'he: pos = 2'h1; 23 4'hf: pos = 2'h0; 24 default: pos = 2'b0; // Default case is not strictly necessary because all 16 combinations are covered. 25 endcase 26 end 27 28 // There is an easier way to code this. See the next problem (always_casez). 29 30 endmodule
但是對於本題我覺得使用case語句太過於繁瑣,后來嘗試使用if else語句成功減少了代碼量並成功運行。
1 module top_module ( 2 input [3:0] in, 3 output reg [1:0] pos ); 4 always @(*) 5 begin 6 if(in[0] == 1) 7 pos = 2'd00; 8 else if(in[1] == 1) 9 pos = 2'd01; 10 else if(in[2] == 1) 11 pos = 2'd10; 12 else if(in[3] == 1) 13 pos = 2'd11; 14 else 15 pos = 2'd00; 16 end 17 18 endmodule
在casez語句中可以利用字母'z'來表示該位置可以為任意狀態,例如4'bzzz1表示在最低位為1時便可執行該項對應命令,這樣可以極大減少代碼量,如上面所示。
由此可以利用此特性編寫8位的優先級編碼器。
題目:
Build a priority encoder for 8-bit inputs. Given an 8-bit vector, the output should report the first bit in the vector that is 1. Report zero if the input vector has no bits that are high. For example, the input 8'b10010000 should output 3'd4, because bit[4] is first bit that is high.
答案:
1 module top_module ( 2 input [7:0] in, 3 output reg [2:0] pos ); 4 always @(*) 5 begin 6 casez(in) 7 8'bzzzzzzz1 : pos = 3'b000; 8 8'bzzzzzz10 : pos = 3'b001; 9 8'bzzzzz100 : pos = 3'b010; 10 8'bzzzz1000 : pos = 3'b011; 11 8'bzzz10000 : pos = 3'b100; 12 8'bzz100000 : pos = 3'b101; 13 8'bz1000000 : pos = 3'b110; 14 8'b10000000 : pos = 3'b111; 15 default : pos = 3'b000; 16 endcase 17 end 18 19 endmodule
在使用always語句時要注意所有輸入的狀態都要對應一個合理的輸出,在case語句使用也是同樣的道理,為了實現這一准則,可以在執行case語句前完成各個輸出管腳的初始化。
題目:Always nolatches
Suppose you're building a circuit to process scancodes from a PS/2 keyboard for a game. Given the last two bytes of scancodes received, you need to indicate whether one of the arrow keys on the keyboard have been pressed. This involves a fairly simple mapping, which can be implemented as a case statement (or if-elseif) with four cases.
答案:
1 module top_module ( 2 input [15:0] scancode, 3 output reg left, 4 output reg down, 5 output reg right, 6 output reg up ); 7 8 always @(*) begin 9 up = 1'b0; 10 down = 1'b0; 11 left = 1'b0; 12 right = 1'b0; 13 case(scancode) 14 16'he06b : left = 1'b1; 15 16'he072 : down = 1'b1; 16 16'he074 : right = 1'b1; 17 16'he075 : up = 1'b1; 18 default : begin up = 1'b0; down = 1'b0; left = 1'b0; right = 1'b0; end 19 endcase 20 end 21 22 endmodule