zoukankan      html  css  js  c++  java
  • Verilog HDL刷题笔记(03)

    [注]这个网站比较神奇的一点就在于,不解出来就不让你看答案。所以经常一个错误卡好久。。不过有大佬在GitHub发过答案了:

    https://github.com/M-HHH/HDLBits_Practice_verilog

    ---------

    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 out_assign = (sel_b1&sel_b2) ? b : a;
        always@(*)
            if (sel_b1&sel_b2) 
                out_always=b;
            else 
                out_always=a;
    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.

    // 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
            shut_off_computer=cpu_overheated;
        end
        always @(*) begin
            keep_driving=(~arrived)&(~gas_tank_empty);
        end
    endmodule
    
    
    //-2/if语句条件不全的话会有latch;
    // 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)&(~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. Be careful of inferring latches (See.always_if2)

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

    // synthesis verilog_input_version verilog_2001
    module top_module (
        input [3:0] in,
        output reg [1:0] pos  );
        always@(*) begin
            case(in)
                4'b0000:pos=2'b00;
                4'b0001:pos=2'b00;
                4'b0010:pos=2'b01;
                4'b0011:pos=2'b00;
                4'b0100:pos=2'b10;
                4'b0101:pos=2'b00;
                4'b0110:pos=2'b01;
                4'b0111:pos=2'b00;
                4'b1000:pos=2'b11;
                4'b1001:pos=2'b00;
                4'b1010:pos=2'b01;
                4'b1011:pos=2'b00;
                4'b1100:pos=2'b10;
                4'b1101:pos=2'b00;
                4'b1110:pos=2'b01;
                4'b1111:pos=2'b00;
            endcase
        end
    endmodule

    /*
    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.

    From the previous exercise (always_case2), there would be 256 cases in the case statement. We can reduce this (down to 9 cases) if the case items in the case statement supported don't-care bits. This is what casez is for: It treats bits that have the value z as don't-care in the comparison.

    // 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
    // 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;
                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);//
        wire [7:0] minab,mincd;
        assign minab=(a>b)?b:a;
        assign mincd=(c>d)?d:c;
        assign min=(minab>mincd)?mincd:minab;
        // assign intermediate_result1 = compare? true: false;
    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.

    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 
    );
        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
    );
        always@(*)
            begin
                for (integer i=0;i<100;i=i+1)
                    out[i]=in[99-i];
            end
    endmodule

    41.A "population count" circuit counts the number of '1's in an input vector. Build a population count circuit for a 255-bit input vector.

    module top_module( 
        input [254:0] in,
        output [7:0] out );
        always@(*)
            begin
                out=0;
                for (integer i=0;i<255;i=i+1)
                    if (in[i])
                        out=out+1;
                    else
                         ;   
            end
    endmodule
    //Warning (10230): Verilog HDL assignment warning at top_module.v(9): 
    //truncated value with size 32 to match size of target (8)
    //答案 module top_module ( input [254:0] in, output reg [7:0] out ); always @(*) begin // Combinational always block out = 0; for (int i=0;i<255;i++) out = out + in[i]; end endmodule

    42.Create a 100-bit binary ripple-carry adder by instantiating 100 full adders. The adder adds two 100-bit numbers and a carry-in to produce a 100-bit sum and carry out. To encourage you to actually instantiate full adders, also output the carry-out from each full adder in the ripple-carry adder. cout[99] is the final carry-out from the last full adder, and is the carry-out you usually see.

    module top_module( 
        input [99:0] a, b,
        input cin,
        output [99:0] cout,
        output [99:0] sum );
        assign cout[0] = a[0] & b[0] | a[0] & cin | b[0] & cin;
        assign sum[0]  = a[0] ^ b[0] ^ cin;
    
        
        integer i;
        
        always @ (*) begin
            for (i=1; i<100; i++) begin
                cout[i] = a[i] & b[i] | a[i] & cout[i-1] | b[i] & cout[i-1];
                sum[i]  = a[i] ^ b[i] ^ cout[i-1];
            end
        end
    endmodule
    //There are many full adders to instantiate. An instance array or generate statement would help here.
    //这应该不是题目要求的解法

    43.You are provided with a BCD one-digit adder named bcd_fadd that adds two BCD digits and carry-in, and produces a sum and carry-out.

    module bcd_fadd {
        input [3:0] a,
        input [3:0] b,
        input     cin,
        output   cout,
        output [3:0] sum );
    

    Instantiate 100 copies of bcd_fadd to create a 100-digit BCD ripple-carry adder. Your adder should add two 100-digit BCD numbers (packed into 400-bit vectors) and a carry-in to produce a 100-digit sum and carry out.

    module top_module( 
        input [399:0] a, b,
        input cin,
        output cout,
        output [399:0] sum );
        wire [99:0] ccout;
        bcd_fadd inst1 (a[3:0],b[3:0],cin,ccout[0],sum[3:0]);
        genvar i;
        generate
            for (i=1;i<100;i++)
                begin : label
                    bcd_fadd fadd (a[4*i+3:4*i],b[4*i+3:4*i],ccout[i-1],ccout[i],sum[4*i+3:4*i]);
                end
        endgenerate
        assign cout=ccout[99];
    endmodule
    //
    //Warning (10230): Verilog HDL assignment warning at tb_modules.sv(8): truncated value with size 32 to match size 
    //of target (4) File: /var/www/verilog/work/vlgSZma3E_dir/tb_modules.sv Line: 8
    
    //GITHUB的答案
    module top_module( 
        input [399:0] a, b,
        input cin,
        output cout,
        output [399:0] sum );
        
        wire [399:0] cout_tmp;
        bcd_fadd fadd(.a(a[3:0]), .b(b[3:0]), .cin(cin), .cout(cout_tmp[0]),.sum(sum[3:0]));
        assign cout = cout_tmp[396];
        
        generate
            genvar i;
            for(i = 4; i < 400; i=i+4) begin : adder
                bcd_fadd fadd(.a(a[i+3:i]), .b(b[i+3:i]), .cin(cout_tmp[i-4]), .cout(cout_tmp[i]),.sum(sum[i+3:i]));
            end
        endgenerate
    
    endmodule
  • 相关阅读:
    WCF中神秘的“8731"端口和“Design_Time_Addresses”
    wcf分布式构架集群案例解决方案
    asp.net odjectdatasource的用法
    ClientBase<T>中对ChannelFactory<T>的缓存机制
    asp.net datatable中行的复制
    c#连接各种数据库的方法
    wcf系列学习5天速成——事务的使用
    Atitit 软件设计中的各种图纸 uml 之道 1. 常见设计成果与图纸 2 1.1. 总图 2 1.2. ui原型图与html 2 1.3. 业务逻辑 伪代码 各种uml图 2 1.4. 总体
    Atitit 综合原则 软件与项目开发中的理念信念 目录 1.1. 建议组合使用扬长避短 1 1.2. 常见数据库 mysql oracle mssql mongodb postgre sqlit
    Atitit it理论不可能三角“:“安全方便廉价 目录 1. 不可能三角 1 2. 三元悖论 1 2.1. 培恩洛兹三角形 2 2.2. 彭罗斯三角(Penrose triangle) 2 2.
  • 原文地址:https://www.cnblogs.com/kraken7/p/12894494.html
Copyright © 2011-2022 走看看