目前的两种用法:
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