verilog always语法

 

目前的两种用法:

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

 

posted @ 2021-11-18 23:21  super_gotta  阅读(1219)  评论(0编辑  收藏  举报