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的显示:
FPGA作业.2_第1张图片
FPGA作业.2_第2张图片
编译之后,RTL view如下图所示:
FPGA作业.2_第3张图片
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.如图
FPGA作业.2_第4张图片

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译码的资源消耗
FPGA作业.2_第5张图片
416译码的资源消耗
FPGA作业.2_第6张图片
然后可以看一下416的RTL View:
FPGA作业.2_第7张图片

5、无符号加法器
只放一下8输入的加法器的代码图

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

加法器中输出改为4比特的仿真图
FPGA作业.2_第8张图片
可以看到当输出的结果超出了输出所能表示的时候,会出现结果和想象的不一样.
输入为8位的时候的仿真图
FPGA作业.2_第9张图片
可以 看到输出的结果的延迟是是比4输入的时候的延迟要大一些的 。

后面是有符号的加法器和流水线加法器

有符号的加法器
代码实现:

module signadd(
  IN1   ,
  IN2   ,
  OUT   );
input signed [3:0] IN1, IN2;
output signed [3:0] OUT;
reg signed [3:0] OUT;
always@(IN1 or IN2) begin
  OUT = IN1 + IN2;
end
endmodule

编译完之后,进行仿真。仿真时对于数据的负数的实现,要在数据的属性里进行改变,在Radix里面改选为signed decimal,如下图所示:
FPGA作业.2_第10张图片
然后就可以进行负数的编辑了,下面是4位输出的仿真图:
FPGA作业.2_第11张图片
当输入改为8位的时候,再进行编译和仿真,仿真结果如下图:
FPGA作业.2_第12张图片
再然后就是带流水线的加法器
将输入信号改为8比特位宽的,其代码实现如下

module lsxadd(
  IN1   ,
  IN2   ,
  CLK   ,
  OUT   );
input  [7:0] IN1, IN2;
input CLK;
output  [4:0] OUT;
reg [7:0] in1_d1R, in2_d1R;
reg  [4:0] adder_out, OUT;
always@(posedge CLK) begin 
  in1_d1R <= IN1;
  in2_d1R <= IN2;
  OUT     <= adder_out;
end
always@(in1_d1R or in2_d1R) begin 
  adder_out = in1_d1R + in2_d1R;
end
endmodule 

然后仿真:
FPGA作业.2_第13张图片
再添加一级流水线的情况,
代码也是在基础上改动一些:

module lsxadd(
  IN1   ,
  IN2   ,
  CLK   ,
  OUT   );
input  [7:0] IN1, IN2;
input CLK;
output  [4:0] OUT;
reg [7:0] in1_d1R, in2_d1R,in1_d2R,in2_d2R;
reg  [4:0] adder_out, OUT;
always@(posedge CLK) begin 
  in1_d1R <= IN1;
  in2_d1R <= IN2;
  in1_d2R <= in1_d1R;
  in2_d2R <= in2_d1R;
  OUT     <= adder_out;
end
always@(in1_d2R or in2_d2R) begin 
  adder_out = in1_d2R + in2_d2R;
end
endmodule 

看RTL Viewer的情况
FPGA作业.2_第14张图片
再之后就是仿真:
FPGA作业.2_第15张图片
5.2 乘法器的实现
乘法器的基本实现是在加法器的基础上,将加号更换为乘号即可。
8输入输出的无流水线的乘法器的代码实现和仿真

module mul(
  IN1   ,
  IN2   ,
  OUT   );
 input [7:0] IN1, IN2;
 output [7:0] OUT;
 reg [7:0] OUT;
always@(IN1 or IN2) begin // 生成组合逻辑的always 块
  OUT = IN1 * IN2;
end
endmodule 

FPGA作业.2_第16张图片
然后是带流水线的乘法器的实现
代码

module mul(
  IN1   ,
  IN2   ,
  CLK   ,
  OUT   );
 input [7:0] IN1, IN2;
 input CLK;
 output [7:0] OUT;
 reg [7:0] in1_d1R, in2_d1R;
 reg  [7:0] muler_out, OUT;
 
always@(posedge CLK) begin 
  in1_d1R <= IN1;
  in2_d1R <= IN2;
  OUT     <= muler_out;
end

always@(in1_d1R or in2_d1R) begin 
  muler_out = in1_d1R * in2_d1R;
end
endmodule 

编译之后的RTL Viewer如下图:
FPGA作业.2_第17张图片
然后进行仿真
FPGA作业.2_第18张图片
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

仿真结果如下:FPGA作业.2_第19张图片
可以看到当计数到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

波形仿真图如下FPGA作业.2_第20张图片

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 看到,如下图:

FPGA作业.2_第21张图片
仿真结果如下:
当EN为0时,仿真没有结果
FPGA作业.2_第22张图片
当EN为1时,仿真才可以成功捕获:
FPGA作业.2_第23张图片
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为下图所示:
FPGA作业.2_第24张图片
仿真结果如下
FPGA作业.2_第25张图片

你可能感兴趣的:(FPGA作业.2)