初识FPGA:各种RTL小型电路模块的设计

一、4选1多路选择器

1、实现代码举例

module top(out,in0,in1,in2,in3,sel);

parameter wl=2;

Output out;

input  in0,in1,in2,in3;

input [wl-1:0]  sel;

reg  out;

always @(in0 or in1 or in2 or in3 or sel) //敏感信号列表

begin

case(sel)

扫描二维码关注公众号,回复: 4024646 查看本文章

2'b00: out=in0;

2'b01: out=in1;

2'b10: out=in2;

2'b11: out=in3;

default: out=0;

endcase

end

endmodule  

2、仿真RTL图

3、仿真波形图

二、4X4路交叉开关

实际上是选择器的组合体,通常用在复杂一些的信号选通的场合。每一个输出端都有对应的选通信号,用选通信号控制输出端选通到哪个输入端。当输入和输出的端口增加时,该电路会消耗非常多的电路资源。

1、实现代码举例

module top(  IN0,  IN1 ,IN2 , IN3 , SEL0,SEL1,SEL2,SEL3,OUT0,OUT1,OUT2, OUT3);

parameter wl=2;

input  IN0,IN1,IN2,IN3;

input [wl-1:0]SEL0, SEL1, SEL2, SEL3;

output OUT0, OUT1,OUT2,OUT3;

reg  OUT0, OUT1,OUT2,OUT3;

always @ (IN0 or IN1 or IN2 or IN3 or SEL0 ) begin

 case(SEL0)

    2'b00: OUT0 = IN0;

    2'b01: OUT0 = IN1;

    2'b10: OUT0 = IN2;

    2'b11: OUT0 = IN3;

 endcase

end

always @ (IN0 or IN1 or IN2 or IN3 or SEL1 ) begin

 case(SEL1)

    2'b00: OUT1 = IN0;

    2'b01: OUT1 = IN1;

    2'b10: OUT1 = IN2;

    2'b11: OUT1 = IN3;

 endcase

end

always @ (IN0 or IN1 or IN2 or IN3 or SEL2 ) begin

 case(SEL2)

    2'b00: OUT2 = IN0;

    2'b01: OUT2 = IN1;

    2'b10: OUT2 = IN2;

    2'b11: OUT2 = IN3;

 endcase

end

always @ (IN0 or IN1 or IN2 or IN3 or SEL3 ) begin

 case(SEL3)

    2'b00: OUT3 = IN0;

    2'b01: OUT3 = IN1;

    2'b10: OUT3 = IN2;

    2'b11: OUT3 = IN3;

 endcase

end

endmodule

2、仿真RTL图

三、8输入的优先编码器

1、实现代码举例

module top( IN , OUT );

input [7:0] IN;

output[3:0] OUT;

reg   [3:0] OUT;

always @ (IN) begin

   if(IN[7])       

     OUT = 4'b0111;

   else if(IN[6])  

     OUT = 4'b0110;

   else if(IN[5])  

     OUT = 4'b0101;

   else if(IN[4])  

     OUT = 4'b0100;

   else if(IN[3])  

     OUT = 4'b0011;

   else if(IN[2])  

     OUT = 4'b0010;

   else if(IN[1])  

     OUT = 4'b0001;

    else if(IN[0])         

     OUT = 4'b0000;

     else            // 什么都没有检测到

     OUT = 4'b1111;  // 输出值可自定义,不和上面的输出值混淆即可

end

endmodule

2、仿真RTL图

四、4-16译码器

1、实现代码举例

module top( IN,OUT); 

input [3:0] IN;

output[15:0] OUT;

reg   [15:0] OUT;

always @ (IN) begin

  case(IN)

    4'b0000: OUT = 16'b0000000000000001;

    4'b0001: OUT = 16'b0000000000000010;

    4'b0010: OUT = 16'b0000000000000100;

    4'b0011: OUT = 16'b0000000000001000;

    4'b0100: OUT = 16'b0000000000010000;

    4'b0101: OUT = 16'b0000000000100000;

    4'b0110: OUT = 16'b0000000001000000;

    4'b0111: OUT = 16'b0000000010000000;

    4'b1000: OUT = 16'b0000000100000000;

    4'b1001: OUT = 16'b0000001000000000;

    4'b1010: OUT = 16'b0000010000000000;

    4'b1011: OUT = 16'b0000100000000000;

    4'b1100: OUT = 16'b0001000000000000;

    4'b1101: OUT = 16'b0010000000000000;

    4'b1110: OUT = 16'b0100000000000000;

    4'b1111: OUT = 16'b1000000000000000;

    //  full case 不需要写default,否则一定要有default

  endcase

end

endmodule

2、仿真RTL图

输入序列位数越大,仿真的资源开销越大

五、加法器

1、无符号加法器

(1)实现代码举例(四输入四输出)

module top( IN1,IN2,OUT);

input[3:0] IN1, IN2;

output[3:0] OUT;

reg[3:0] OUT;

always@(IN1 or IN2) begin // 生成组合逻辑的always 块

  OUT = IN1 + IN2;

end

endmodule

(2)仿真波形图

如果增加输入位数,波形延迟也将增加,一旦输出超出给定的位宽,波形将从最低位开始显示,高位将显示不了。

2、有符号加法器

(1)实现代码举例(四输入四输出)

module top( IN1   ,IN2   , OUT   );

input signed [3:0] IN1, IN2;

output signed [3:0] OUT;

reg signed [3:0] OUT;

always@(IN1 or IN2) begin // 生成组合逻辑的always 块

  OUT = IN1 + IN2;

end

endmodule

(2)仿真波形图

3、带流水线的加法器

(1)实现代码举例(八输入五输出,含两级流水线)

module top( IN1   ,IN2   ,CLK   ,OUT   );

input  [7:0] IN1, IN2;

input CLK;

output  [4:0] OUT;

reg [7:0] in1_d1R, in2_d1R,in11_d1R, in22_d1R;

reg  [4:0] adder_out1,OUT;

always@(posedge CLK) begin // 生成D触发器的always块

  in1_d1R <= IN1;

  in2_d1R <= IN2;

  in11_d1R <= in1_d1R;

  in22_d1R <= in2_d1R;

  OUT     <= adder_out1;

end

always@(in11_d1R or in22_d1R) begin // 生成组合逻辑的always 块

  adder_out1=in11_d1R+in22_d1R;

end

endmodule

(2)仿真RTL图

(3)仿真波形图

和不带流水线的加法器相比,毛刺的时间长度变短变少,因为加入的D触发器使得对应的输入和输出同步起来,总体输出晚了四个时钟。输入数据和其对应的结果不在一个时钟周期。

六、带流水线的无符号乘法器

1、实现代码举例

module top( IN1   , IN2   ,CLK   , OUT   );

 input [3:0] IN1, IN2;

 input  CLK   ;

 output [7:0] OUT;

 reg [3:0] in1_d1R, in2_d1R;

reg  [7:0] adder_out, OUT;

always@(posedge CLK) begin // 生成D触发器的always块

  in1_d1R <= IN1;

  in2_d1R <= IN2;

  OUT     <= adder_out;

end

always@(in1_d1R or in2_d1R) begin // 生成组合逻辑的always 块

  adder_out = in1_d1R * in2_d1R;

end

endmodule

2、仿真RTL图

3、仿真波形图

没有硬件乘法器的FPGA芯片编译之后的资源开销远远增大。和不带流水线的乘法器相比,毛刺的时间长度变短变少,因为加入的D触发器使得对应的输入和输出同步起来,总体输出晚了3个时钟。输入数据和其对应的结果不在一个时钟周期。

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/SBDYONE/article/details/83956012