1. 程式人生 > >FPGA作業.2

FPGA作業.2

2、關於4X4交叉開關 在已有程式碼的基礎上進行了修改

module mux44(in0,in1,in2,in3,out0,out1,out2,out3,sl0,sl1,sl2,sl3);  
parameter WL = 16;
input [WL-1:0] in0,in1,in2,in3;
input sl0,sl1,sl2,sl3;
output[WL-1:0] out0,out1,out2,out3;
reg   [WL-1:0] out0,out1,out2,out3;
always @ (in0 or in1 or in2 or in3 or out0 or sl0 or sl1) begin
  if((sl0)&&(sl1))
    out0=in3;
  else 
if((!sl0)&&(sl1))
    out0=in2;
  else
  if((sl0)&&(!sl1))
  out0=in1;
  else 
  out0=in0;   
end
always @ (in0 or in1 or in2 or in3 or out1 or sl1 or sl2) begin
  if((sl1)&&(sl2))
    out1=in3;
  else 
  if((!sl1)&&(sl2))
    out1=in2;
  else
  if((sl1)&&(!sl2))
  out1=in1;
  else 
  out1=in0;   
end
always @ (in0 or in1 or in2 or in3 or out2 or sl2 or sl3) begin
  if((sl2)&&(sl3))
    out2=in3;
  else 
if((!sl2)&&(sl3))
    out2=in2;
  else
  if((sl2)&&(!sl3))
  out2=in1;
  else 
  out2=in0;   
end
always @ (in0 or in1 or in2 or in3 or out3 or sl0 or sl3) begin
  if((sl0)&&(sl3))
    out3=in3;
  else 
if((!sl0)&&(sl3))
    out3=in2;
  else
  if((sl0)&&(!sl3))
  out3=in1;
  else 
  out3=in0;   
end
endmodule

下面是進行編譯之後的資源消耗的顯示。上圖為4X4,下圖是2X2的顯示: 4x4 在這裡插入圖片描述 編譯之後,RTL view如下圖所示: RTL 3、這題為做一個8位優先選擇器,程式碼相對簡單,如下面展示:

module YX(
  IN        ,   
  OUT       );  
input [7:0] IN;
output[3:0] OUT;

reg   [3:0] OUT;

always @ (IN) begin
   if(IN[7])       
     OUT = 3'b0111;
   else if(IN[6])  
     OUT = 3'b0110;
   else if(IN[5])  
     OUT = 3'b0101;
   else if(IN[4])  
     OUT = 3'b0100;
   else if(IN[3])           
     OUT = 3'b0011; 
   else if(IN[2])
     OUT = 3'b0010;
   else if(IN[1])
     OUT = 3'b0001;
   else if(IN[0])
     OUT = 3'b0000;
   else 
     OUT = 3'b1111;

end
endmodule

編譯之後,觀看RTL View.如圖 在這裡插入圖片描述

4、關於38譯碼器和416譯碼器 關於416譯碼器的程式碼的編寫,也是在38譯碼器的基礎上進行修改。

module yiima416(
  IN        ,   
  OUT       );  
input [3:0] IN;
output[15:0] OUT;
reg   [15:0] OUT;
always @ (IN) begin
  case(IN)
    4'b0000: OUT = 16'b0000_0000_0000_0001;
    4'b0001: OUT = 16'b0000_0000_0000_0010;
    4'b0010: OUT = 16'b0000_0000_0000_0100;
    4'b0011: OUT = 16'b0000_0000_0000_1000;
    4'b0100: OUT = 16'b0000_0000_0001_0000;
    4'b0101: OUT = 16'b0000_0000_0010_0000;
    4'b0110: OUT = 16'b0000_0000_0100_0000;
    4'b0111: OUT = 16'b0000_0000_1000_0000;
    4'b1000: OUT = 16'b0000_0001_0000_0000;
    4'b1001: OUT = 16'b0000_0010_0000_0000;
    4'b1010: OUT = 16'b0000_0100_0000_0000;
    4'b1011: OUT = 16'b0000_1000_0000_0000;
    4'b1100: OUT = 16'b0001_0000_0000_0000;
    4'b1101: OUT = 16'b0010_0000_0000_0000;
    4'b1110: OUT = 16'b0100_0000_0000_0000;
    4'b1111: OUT = 16'b1000_0000_0000_0000;
  endcase
end
endmodule

然後進行編譯,可以看到38和416的資源消耗是差一倍的。 38譯碼的資源消耗 在這裡插入圖片描述 416譯碼的資源消耗 在這裡插入圖片描述 然後可以看一下416的RTL View: 在這裡插入圖片描述

5、無符號加法器 只放一下8輸入的加法器的程式碼圖

module addunsign(
  IN1   ,
  IN2   ,
  OUT   );
input[7:0] IN1, IN2;
output[4:0] OUT;
reg[4:0] OUT;
[email protected](IN1 or IN2) begin 
  OUT = IN1 + IN2;
end
endmodule

加法器中輸出改為4位元的模擬圖 在這裡插入圖片描述 可以看到當輸出的結果超出了輸出所能表示的時候,會出現結果和想象的不一樣. 輸入為8位的時候的模擬圖 在這裡插入圖片描述 可以 看到輸出的結果的延遲是是比4輸入的時候的延遲要大一些的 。

後面是有符號的加法器和流水線加法器

6、計數器 只有clk輸入和OV輸出的計數器,其程式碼如下:

module count1( clk, ov);
input clk;
output ov;
reg [3:0]  cnt_next;
reg ov;
parameter CNT_MAX_VAL = 9;
always @ (posedge clk) begin
if(cnt_next < CNT_MAX_VAL) begin 
          ov=0;
          cnt_next = cnt_next + 1'b1;
        end
        else begin 
          ov=1;
          cnt_next = 0;
        end
end
endmodule

模擬結果如下:在這裡插入圖片描述 可以看到當計數到10的時候就會計1,然後接著計數

然後是相對複雜的一個計數器

module cntcom(
  RST   , 
  CLK   , 
  EN    , 
  CLR   , 
  LOAD  , 
  DATA  , 
  CNTVAL, 
  OV    );

input RST   , CLK   , EN    , CLR   , LOAD  ;
input [3:0] DATA ;
output [3:0] CNTVAL;
output OV;   

reg [3:0] CNTVAL, cnt_next;
reg OV;

parameter CNT_MAX_VAL = 9;


always @(EN or CLR or LOAD or DATA or CNTVAL) begin
  if(CLR) begin 
      cnt_next = 0;
    end
    else begin  
    if(EN) begin    
      if(LOAD) begin 
        cnt_next = DATA;
      end
      else begin     
        if(CNTVAL < CNT_MAX_VAL) begin 
          cnt_next = CNTVAL + 1'b1;
        end
        else begin 
          cnt_next = 0;
        end
      end 
      end 
  else begin  
    cnt_next = CNTVAL;
  end 
end
end  
  
always @ (posedge CLK or posedge RST) begin
  if(RST) 
    CNTVAL <= 0;
  else
    CNTVAL <= cnt_next;
end
always @ (CNTVAL) begin
  if(CNTVAL == CNT_MAX_VAL) 
    OV = 1;
  else
    OV = 0;
end

endmodule

波形模擬圖如下在這裡插入圖片描述

7、狀態機 程式碼如下

module yiwei(
  CLK       ,   
  EN        ,
  RST       ,   
  CENT1IN   ,  
  TINOUT    );  

input  CLK       ; 
input  RST       ; 
input  CENT1IN   ; 
input  EN        ;
output TINOUT    ;

parameter ST_0_CENT = 0;
parameter ST_1_CENT = 1;
parameter ST_2_CENT = 2;
parameter ST_3_CENT = 3;
parameter ST_4_CENT = 4;

reg [4-2:0]stateR       ;
reg [4-2:0]next_state   ;
reg        TINOUT       ;
always @ (CENT1IN or stateR) begin
  case (stateR)
    ST_0_CENT :begin if(CENT1IN) next_state = ST_1_CENT ; else next_state = ST_0_CENT; end
    ST_1_CENT :begin if(CENT1IN) next_state = ST_2_CENT ; else next_state = ST_0_CENT; end
    ST_2_CENT :begin if(!CENT1IN) next_state = ST_3_CENT ; else next_state = ST_0_CENT; end
    ST_3_CENT :begin if(CENT1IN) next_state = ST_4_CENT ; else next_state = ST_0_CENT; end
    ST_4_CENT :begin next_state = ST_0_CENT ;end
  endcase
end
always @ (stateR) begin
  if(EN) begin
  if(stateR == ST_4_CENT) 
    TINOUT = 1'b1;
  else 
    TINOUT = 1'b0;
end
end
// state DFF
always @ (posedge CLK or posedge RST)begin
  if(RST)
    stateR <= ST_0_CENT;
  else
    stateR <= next_state;
end

endmodule

上面的程式碼是一個帶有EN使能的狀態機,當遇到1011時,輸出為1,否則輸出就為0. 狀態轉移圖也可以通過Tools-Netlist Viewers-State Machine Viewer 看到,如下圖:

在這裡插入圖片描述 模擬結果如下: 當EN為0時,模擬沒有結果 在這裡插入圖片描述 當EN為1時,模擬才可以成功捕獲: 在這裡插入圖片描述 8、併入串出的移位暫存器 程式碼如下圖所以

module crbc(
  RST   ,   
  CLK   ,   
  EN    ,   
  LOAD  ,
  IN    ,   
  OUT   );  

input RST, CLK, EN, LOAD;
input [3:0]IN;
output OUT;
reg [3:0] shift_R;
reg OUT;

always @ (posedge CLK or posedge RST or posedge LOAD) begin
  if(RST) 
    shift_R[3:0] <= 0;
  else begin
   if(LOAD) begin
      shift_R[3:0] <= IN[3:0];
      end
      else begin
    if(EN) begin 
      OUT = shift_R[3];
      shift_R[3:1] <= shift_R[2:0];
      shift_R[0]   <= 0;
    end
    else begin 
      shift_R[3:0] <= shift_R[3:0];
    end
end 
end
end
endmodule

RTL View為下圖所示: 在這裡插入圖片描述 模擬結果如下 在這裡插入圖片描述