1. 程式人生 > 其它 >FPGA學習: Verilog刷題記錄(2)

FPGA學習: Verilog刷題記錄(2)

技術標籤:FPGA

FPGA學習: Verilog刷題記錄(2)

刷題網站 : HDLBits

第二章 : Verilog Language

第二節 :Vectors

  • Vectors

    • 題目描述:Build a circuit that has one 3-bit input, then outputs the same vector, and also splits it into three separate 1-bit outputs. Connect output o0 to the input vector’s position 0, o1 to position 1, etc

      在這裡插入圖片描述

    • 題目分析:熟悉verilog中vector的操作,將輸入的3位訊號賦值給outv和分別給o2,o1,o0,利用assign進行賦值

    • 解答:

      /*我的解答*/
      module top_module ( 
          input wire [2:0] vec,
          output wire [2:0] outv,
          output wire o2,
          output wire o1,
          output wire o0  ); // Module body starts after module declaration
          
        	assign outv = vec;
          assign {o0,o1,o2} = {vec[0],vec[1],vec[2]};
        
      endmodule
      
      
      /*官網的解答*/
      module top_module(
      	input [2:0] vec, 
      	output [2:0] outv,
      	output o2,
      	output o1,
      	output o0
      );
      	
      	assign outv = vec;
      
      	// This is ok too: assign {o2, o1, o0} = vec;
      	assign o0 = vec[0];
      	assign o1 = vec[1];
      	assign o2 = vec[2];
      	
      endmodule
      
      
  • Vectors in more detail

    • 題目描述: Build a combinational circuit that splits an input half-word (16 bits, [15:0] ) into lower [7:0] and upper [15:8] bytes.

    • 題目分析:將輸入的高8位賦值給out_hi,低八位賦值給out_lo即可

    • 解答:

      /*我的解答*/
      `default_nettype none     // Disable implicit nets. Reduces some types of bugs.
      module top_module( 
          input wire [15:0] in,
          output wire [7:0] out_hi,
          output wire [7:0] out_lo );
      
          assign out_lo = in[7:0];
          assign out_hi = in[15:8];
          
      endmodule
      
      /*官網解答*/
      module top_module (
      	input [15:0] in,
      	output [7:0] out_hi,
      	output [7:0] out_lo
      );
      	
      	assign out_hi = in[15:8];
      	assign out_lo = in[7:0];
      	
      	// Concatenation operator also works: assign {out_hi, out_lo} = in;
      	
      endmodule
      
  • Vector part select

    • 題目描述:Build a circuit that will reverse the byte ordering of the 4-byte word.

      AaaaaaaaBbbbbbbbCcccccccDddddddd => DdddddddCcccccccBbbbbbbbAaaaaaaa
      
    • 題目分析:題目的意思就是將in的低位以8位vector依次賦值給out的高位,同樣是以向量的形式

    • 解答:

      /*我的解答*/
      module top_module( 
          input [31:0] in,
          output [31:0] out );//
      
          assign {out[31:24],out[23:16],out[15:8],out[7:0]} = {in[7:0],in[15:8],in[23:16],in[31:24]};
      
      endmodule
      
      /*官網解答*/
      module top_module (
      	input [31:0] in,
      	output [31:0] out
      );
      
      	assign out[31:24] = in[ 7: 0];	
      	assign out[23:16] = in[15: 8];	
      	assign out[15: 8] = in[23:16];	
      	assign out[ 7: 0] = in[31:24];	
      	
      endmodule
      
      
  • Bitwise operators

    • 題目描述:Build a circuit that has two 3-bit inputs that computes the bitwise-OR of the two vectors, the logical-OR of the two vectors, and the inverse (NOT) of both vectors. Place the inverse of b in the upper half of out_not (i.e., bits [5:3]), and the inverse of a in the lower half.
      在這裡插入圖片描述

    • 題目分析:實際上也是看圖寫程式碼,該題目主要想讓我們知道,邏輯運算和按位運算的區別,如果是進行一位的運算時,則用邏輯運算和按位運算是一樣的,當進行多位的運算時,則有所不同,邏輯運算最後的結果只有0或1兩種結果,而按位運算則保留原來的位數

    • 解答:

      /*我的解答*/
      module top_module( 
          input [2:0] a,
          input [2:0] b,
          output [2:0] out_or_bitwise,
          output out_or_logical,
          output [5:0] out_not
      );
          
          assign out_or_bitwise = a | b;
          assign out_or_logical = a || b;
          assign out_not        = {~b,~a};
      
      endmodule
      
      /*官網解答*/
      module top_module(
      	input [2:0] a, 
      	input [2:0] b, 
      	output [2:0] out_or_bitwise,
      	output out_or_logical,
      	output [5:0] out_not
      );
      	
      	assign out_or_bitwise = a | b;
      	assign out_or_logical = a || b;
      
      	assign out_not[2:0] = ~a;	// Part-select on left side is o.
      	assign out_not[5:3] = ~b;	//Assigning to [5:3] does not conflict with [2:0]
      	
      endmodule
      
      
  • Four-input gates

    • 題目描述: Build a combinational circuit with four inputs, in[3:0].

      There are 3 outputs:

      • out_and: output of a 4-input AND gate.
      • out_or: output of a 4-input OR gate.
      • out_xor: output of a 4-input XOR gate.
    • 題目分析:構建三個邏輯閘,只不過輸入是以向量的形式,可以將向量中的每一位提出來進行運算,也可以採用簡略的寫法如下程式碼所示。

    • 解答:

      /*我的解答*/
      
      module top_module( 
          input [3:0] in,
          output out_and,
          output out_or,
          output out_xor
      );
          
          assign out_and = in[0] & in[1] & in[2] & in[3]; 
          assign out_or  = in[0] | in[1] | in[2] | in[3];
          assign out_xor = in[0] ^ in[1] ^ in[2] ^ in[3];
      
          /*
          	或者
          assign out_and = ∈
          assign out_or  = |in;
          assign out_xor = ^in;
          */
          
      endmodule
      
      /*官網解答*/
      	無
      
  • Vector concatenation operator

    • 題目描述: Given several input vectors, concatenate them together then split them up into several output vectors. There are six 5-bit input vectors: a, b, c, d, e, and f, for a total of 30 bits of input. There are four 8-bit output vectors: w, x, y, and z, for 32 bits of output. The output should be a concatenation of the input vectors followed by two 1 bits:
      在這裡插入圖片描述

    • 題目分析:該題主要讓我們熟悉位拼接符的用法,有6個5位輸入的向量,根據圖示將它們賦值給4個8位輸出的向量,例如w是由a和b的高3位組成,x是由b的低2位,c和d的一高位組成

    • 解答:

      /*我的解答*/
      module top_module (
          input [4:0] a, b, c, d, e, f,
          output [7:0] w, x, y, z );
      
          // assign { ... } = { ... };
          assign w[7:0] = {a,b[4:2]};
          assign x[7:0] = {b[1:0],c,d[4:4]};
          assign y[7:0] = {d[3:0],e[4:1]};
          assign z[7:0] = {e[0:0],f,{2{1'b1}}}; 
      endmodule
      
      //其中z用位拼接符的時候需要注意,如果寫成assign z[7:0] = {e[0:0],f,2{1'b1}}是錯誤的,出錯的原因出在2{1'b1},當需要多次使用{}時,需要將其包裹起來即{2{1'b1}},下面有一節“more replication”還可以看到。
      
      /*官網解答*/
      	無
      
      
  • Vector reversal 1

    • 題目描述:Given an 8-bit input vector [7:0], reverse its bit ordering.

    • 題目分析:題目意思即將輸入訊號的從低位到高位賦值給輸出訊號,這題位數不多可以直接利用{}進行拼接,但當位數過多時,採用generate語句進行生成,官網的解答給了出來

    • 解答:

      /*我的解答*/
      module top_module( 
          input [7:0] in,
          output [7:0] out
      );
          assign out = {in[0],in[1],in[2],in[3],in[4],in[5],in[6],in[7]};
          
      endmodule
      
      
      
      /*官網解答*/
      module top_module (
      	input [7:0] in,
      	output [7:0] out
      );
      	
      	assign {out[0],out[1],out[2],out[3],out[4],out[5],out[6],out[7]} = in;
      	
      	/*
      	// I know you're dying to know how to use a loop to do this:
      
      	// Create a combinational always block. This creates combinational logic that computes the same result
      	// as sequential code. for-loops describe circuit *behaviour*, not *structure*, so they can only be used 
      	// inside procedural blocks (e.g., always block).
      	// The circuit created (wires and gates) does NOT do any iteration: It only produces the same result
      	// AS IF the iteration occurred. In reality, a logic synthesizer will do the iteration at compile time to
      	// figure out what circuit to produce. (In contrast, a Verilog simulator will execute the loop sequentially
      	// during simulation.)
      	always @(*) begin	
      		for (int i=0; i<8; i++)	// int is a SystemVerilog type. Use integer for pure Verilog.
      			out[i] = in[8-i-1];
      	end
      
      
      	// It is also possible to do this with a generate-for loop. Generate loops look like procedural for loops,
      	// but are quite different in concept, and not easy to understand. Generate loops are used to make instantiations
      	// of "things" (Unlike procedural loops, it doesn't describe actions). These "things" are assign statements,
      	// module instantiations, net/variable declarations, and procedural blocks (things you can create when NOT inside 
      	// a procedure). Generate loops (and genvars) are evaluated entirely at compile time. You can think of generate
      	// blocks as a form of preprocessing to generate more code, which is then run though the logic synthesizer.
      	// In the example below, the generate-for loop first creates 8 assign statements at compile time, which is then
      	// synthesized.
      	// Note that because of its intended usage (generating code at compile time), there are some restrictions
      	// on how you use them. Examples: 1. Quartus requires a generate-for loop to have a named begin-end block
      	// attached (in this example, named "my_block_name"). 2. Inside the loop body, genvars are read only.
      	generate
      		genvar i;
      		for (i=0; i<8; i = i+1) begin: my_block_name
      			assign out[i] = in[8-i-1];
      		end
      	endgenerate
      	*/
      	
      endmodule
      
      需要注意的是
      1.assign out[7:0] = in[0:7]; 這種宣告在verilog中是不允許的
      
  • Replication operator

    • 題目描述:Build a circuit that sign-extends an 8-bit number to 32 bits. This requires a concatenation of 24 copies of the sign bit (i.e., replicate bit[7] 24 times) followed by the 8-bit number itself.

    • 題目分析:

    • 解答: 題目的意思是將輸入訊號的高位賦值24次,並和原來的訊號進行拼接

      /*我的解答*/
      module top_module (
          input [7:0] in,
          output [31:0] out );//
      
          // assign out = { replicate-sign-bit , the-input };
          assign out = {{24{in[7]}},in};
      
      endmodule
      
      /*官網解答*/
      module top_module (
      	input [7:0] in,
      	output [31:0] out
      );
      
      	// Concatenate two things together:
      	// 1: {in[7]} repeated 24 times (24 bits)
      	// 2: in[7:0] (8 bits)
      	assign out = { {24{in[7]}}, in };
      	
      endmodule
      
      
  • More replication

    • 題目描述: Given five 1-bit signals (a, b, c, d, and e), compute all 25 pairwise one-bit comparisons in the 25-bit output vector. The output should be 1 if the two bits being compared are equal.
      在這裡插入圖片描述

    • 題目分析:熟悉複製的操作,將所給的5位訊號進行如圖所示的組合並將它們進行同或操作

    • 解答:

      /*我的解答*/
      module top_module (
          input a, b, c, d, e,
          output [24:0] out );//
      
          // The output is XNOR of two vectors created by 
          // concatenating and replicating the five inputs.
          // assign out = ~{ ... } ^ { ... };
          assign out = ~{{5{a}},{5{b}},{5{c}},{5{d}},{5{e}}} ^ {5{a,b,c,d,e}};
      endmodule
      
      /*官網解答*/
      module top_module (
      	input a, b, c, d, e,
      	output [24:0] out
      );
      
      	wire [24:0] top, bottom;
      	assign top    = { {5{a}}, {5{b}}, {5{c}}, {5{d}}, {5{e}} };
      	assign bottom = {5{a,b,c,d,e}};
      	assign out = ~top ^ bottom;	// Bitwise XNOR
      
      	// This could be done on one line:
      	// assign out = ~{ {5{a}}, {5{b}}, {5{c}}, {5{d}}, {5{e}} } ^ {5{a,b,c,d,e}};
      	
      endmodule
      

總結

  1. 如何宣告一個vectors

    
      type [upper:lower] vectors_name
      type 通常是wire或reg型,如果要宣告埠則type也可以表示為input或output
       /*example*/
      wire [7:0] w;         // 8-bit wire
      reg  [4:1] x;         // 4-bit reg
      output reg [0:0] y;   // 1-bit reg that is also an output port (this is still a vector)
      input wire [3:-2] z;  // 6-bit wire input (negative ranges are allowed)
      output [3:0] a;       // 4-bit output wire. Type is 'wire' unless specified otherwise.
      wire [0:7] b;         // 8-bit wire where b[0] is the most-significant bit.
    
    
  2. 關於隱式的網路以及如何避免

    隱性的網路通常是我們難以檢測的bug,
    net型別訊號可以通過assign語句或將未宣告的內容附加到模組埠來隱式建立,
    隱性的網路總是一位的wire 如果我們想要用vectors則會出現錯誤 用下列例子說明
    
    wire [2:0] a, c;   // Two vectors
    assign a = 3'b101;  // a = 101
    assign b = a;       // b =   1  implicitly-created wire
    assign c = b;       // c = 001  <-- bug
    my_module i1 (d,e); // d and e are implicitly one-bit wide if not declared.
                    // This could be a bug if the port was intended to be a vector.
    
    通常我們通過新增 `default_nettype none,來讓這類錯誤變得可視
    
  3. 向量進行部分選擇的操作

    類似於程式設計中“切片”的操作
    input [15:0] in;
    output [23:0] out;
    assign {out[7:0], out[15:8]} = in;         // Swap two bytes. Right side and left side are both 16-bit vectors.
    assign out[15:0] = {in[7:0], in[15:8]};    // This is the same thing.
    assign out = {in[7:0], in[15:8]};       // This is different. The 16-bit vector on the right is extended to
                                            // match the 24-bit vector on the left, so out[23:16] are zero.
                                            // In the first two examples, out[23:16] are not assigned.
    
  4. 位拼接符{}的使用

      {3'b111, 3'b000} => 6'b111000
      {1'b1, 1'b0, 3'b101} => 5'b10101
      {4'ha, 4'd10} => 8'b10101010     // 4'ha and 4'd10 are both 4'b1010 in binary
    
      The replication operator allows repeating a vector and concatenating them together:
      可以進行復制的操作
     {num{vector}}
     num:必須是一個常量,並且兩邊的{}是不可以缺少的
    
      Examples:
    
      {5{1'b1}}           // 5'b11111 (or 5'd31 or 5'h1f)
      {2{a,b,c}}          // The same as {a,b,c,a,b,c}
      {3'd5, {2{3'd6}}}   // 9'b101_110_110. It's a concatenation of 101 with
                          // the second vector, which is two copies of 3'b110.