Verilog 刷题笔记(04)

29.Build an AND gate using both an assign statement and a combinational always block. 

// synthesis verilog_input_version verilog_2001
module top_module(
    input a, 
    input b,
    output wire out_assign,
    output reg out_alwaysblock
);

    //assign语句 和 always块 是等效的
    assign out_assign = a&b;
    always@(*) out_alwaysblock = a&b;
    
endmodule

 

 

30. 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.

 

// synthesis verilog_input_version verilog_2001
module top_module(
    input clk,
    input a,
    input b,
    output wire out_assign,
    output reg out_always_comb,
    output reg out_always_ff   );

    //1.连续赋值	assign语句
    assign out_assign = a^b	;			//a异或b
    
    //2.阻塞赋值	always块
    always@(*) out_always_comb = a^b;	//a异或b
    
    //3.非阻塞赋值	always块 + 边沿触发
    always@(posedge clk)
        out_always_ff <= a^b;			//a异或b
endmodule

输出图像:

 

 

31. Build a 2-to-1 mux that chooses between a and b. Choose b if both sel_b1 and sel_b2 are true. Otherwise, choose a. Do the same twice, once using assign statements and once using a procedural if statement.

 

 

// 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版 多路复用
    assign out_assign = (sel_b1&sel_b2)?b:a;
    
    //always版 多路复用
    always@(*)
        if(sel_b1&sel_b2)begin
            out_always = b;
        end
    	else begin
            out_always = a;
        end

endmodule

 

 

32. The following code contains incorrect behaviour that creates a latch. Fix the bugs so that you will shut off the computer only if it's really overheated, and stop driving if you've arrived at your destination or you need to refuel.

 

修改前:

module top_module (
    input      cpu_overheated,
    output reg shut_off_computer,
    input      arrived,
    input      gas_tank_empty,
    output reg keep_driving  ); 

    always @(*) begin
        shut_off_computer=cpu_overheated;
    end
    always @(*) begin
        keep_driving=(~arrived)&(~gas_tank_empty);
    end
endmodule

修改后:

// synthesis verilog_input_version verilog_2001
//注:必须写全if else,否则会出现latch,报错
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)&(~gas_tank_empty))
           keep_driving = 1;
        else
           keep_driving = 0;     
    end

endmodule

 

33.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.

 

// synthesis verilog_input_version verilog_2001
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;
            3'b110:	out<=4'b0000;
            3'b111:	out<=4'b0000;
        endcase
    end

endmodule

 

 34.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.

//这个当时没做出来,看了别人做的
module top_module ( input [3:0] in, output reg [1:0] pos ); always @(*) begin // Combinational always block case (in) 4'h0: pos = 2'h0; // I like hexadecimal because it saves typing. 4'h1: pos = 2'h0; 4'h2: pos = 2'h1; 4'h3: pos = 2'h0; 4'h4: pos = 2'h2; 4'h5: pos = 2'h0; 4'h6: pos = 2'h1; 4'h7: pos = 2'h0; 4'h8: pos = 2'h3; 4'h9: pos = 2'h0; 4'ha: pos = 2'h1; 4'hb: pos = 2'h0; 4'hc: pos = 2'h2; 4'hd: pos = 2'h0; 4'he: pos = 2'h1; 4'hf: pos = 2'h0; default: pos = 2'b0; // Default case is not strictly necessary because all 16 combinations are covered. endcase end // There is an easier way to code this. See the next problem (always_casez). endmodule
//an easier way

always @(*) begin casez (in[3:0]) 4'bzzz1: out = 0; // in[3:1] can be anything 4'bzz1z: out = 1; 4'bz1zz: out = 2; 4'b1zzz: out = 3; default: out = 0; endcase end

 

35. 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.A case statement behaves as though each item is checked sequentially (in reality, it does something more like generating a giant truth table then making gates). Notice how there are certain inputs (e.g., 4'b1111) that will match more than one case item. The first match is chosen (so 4'b1111 matches the first item, out = 0, but not any of the later ones).

  • There is also a similar casex that treats both x and z as don't-care. I don't see much purpose to using it over casez.

  • The digit ? is a synonym for z. so 2'bz0 is the same as 2'b?0

// synthesis verilog_input_version verilog_2001
module top_module (
    input [7:0] in,
    output reg [2:0] pos  );

    always@(*)begin
        casez(in)
            8'bzzzzzzz1: pos = 0;
            8'bzzzzzz1z: pos = 1;
            8'bzzzzz1zz: pos = 2;
            8'bzzzz1zzz: pos = 3;
            8'bzzz1zzzz: pos = 4;
            8'bzz1zzzzz: pos = 5;
            8'bz1zzzzzz: pos = 6;
            8'b1zzzzzzz: pos = 7;
            default:pos = 0;
        endcase
    end
endmodule

 

36.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. 

Scancode [15:0]Arrow key
16'he06b left arrow
16'he072 down arrow
16'he074 right arrow
16'he075 up arrow
Anything else none
 
 
 
 
 
 
 
 
 
 

Your circuit has one 16-bit input, and four outputs. Build this circuit that recognizes these four scancodes and asserts the correct output.To avoid creating latches, all outputs must be assigned a value in all possible conditions . Simply having a default case is not enough. You must assign a value to all four outputs in all four cases and the default case. This can involve a lot of unnecessary typing. One easy way around this is to assign a "default value" to the outputs before the case statement:

always @(*) begin
    up = 1'b0; down = 1'b0; left = 1'b0; right = 1'b0;
    case (scancode)
        ... // Set to 1 as necessary.
    endcase
end
// 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)
        // Set to 1 as necessary.
        //将上述的键盘的ASCII码和up、down、left、right进行链接
        16'he06b:left = 1'b1;
        16'he072:down = 1'b1;
        16'he074:right = 1'b1;
        16'he075:up = 1'b1;
        default:    ;
    endcase
end

endmodule

 

37.Given four unsigned numbers, find the minimum. Unsigned numbers can be compared with standard comparison operators (a < b). Use the conditional operator to make two-way min circuits, then compose a few of them to create a 4-way min circuit. You'll probably want some wire vectors for the intermediate results. Expected solution length: Around 5 lines.

module top_module (
    input [7:0] a, b, c, d,
    output [7:0] min);

    // assign intermediate_result1 = compare? true: false;
    //三目运算符
    wire [7:0] minab,mincd;
    assign minab=(a>b)?b:a;
    assign mincd=(c>d)?d:c;
    assign min=(minab>mincd)?mincd:minab;
endmodule

 

38. Parity checking is often used as a simple method of detecting errors when transmitting data through an imperfect channel. Create a circuit that will compute a parity bit for a 8-bit byte (which will add a 9th bit to the byte). We will use "even" parity, where the parity bit is just the XOR of all 8 data bits.  Expected solution length: Around 1 line.

//Reduction operators
module
top_module ( input [7:0] in, output parity); //奇偶校验,直接异或 assign parity = ^in[7:0]; endmodule

 

39. Build a combinational circuit with 100 inputs, in[99:0]There are 3 outputs:

  • out_and: output of a 100-input AND gate.
  • out_or: output of a 100-input OR gate.
  • out_xor: output of a 100-input XOR gate.
module top_module( 
    input [99:0] in,
    output out_and,
    output out_or,
    output out_xor 
);
    //在 [99:0] 中构建一个具有 100 个输入的组合电路。
    assign out_and = &in[99:0];    //
    assign out_or = |in[99:0];    //
    assign out_xor = ^in[99:0];    //异或

endmodule

 

40.Given a 100-bit input vector [99:0], reverse its bit ordering.

module top_module( 
    input [99:0] in,
    output [99:0] out
);
    //给定一个 100 位输入向量 [99:0],反转其位顺序。
    always@(*)
        begin
            for(integer i = 0; i < 100;i = i+1)
                out[i] = in[99-i];
            end

endmodule

 

 
 
 
 
 

 

posted @ 2022-02-07 17:58  Rap_caT  阅读(194)  评论(0编辑  收藏  举报