欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

FPGA学习(第5节)-看电路图写出Verilog代码(乘法运算+自加一+模块实例化等)

程序员文章站 2022-07-14 23:21:43
...

有个前一节的设计规范,现在我们通过看电路图写出对应的Verilog代码。

一、简单模块设计

(1)任务说明

FPGA学习(第5节)-看电路图写出Verilog代码(乘法运算+自加一+模块实例化等)

(2)代码实现:

功能分析:输出两数相乘的结果。

图中是一个D触发器和乘法器的组合,可以通过组合逻辑+时序逻辑结合来实现。也可以只在时序逻辑中实现。


FPGA学习(第5节)-看电路图写出Verilog代码(乘法运算+自加一+模块实例化等)

FPGA学习(第5节)-看电路图写出Verilog代码(乘法运算+自加一+模块实例化等)

module mul_module(
    clk    ,
    rst_n  ,
    //其他信号,举例dout
    mul_a  ,
    mul_b  ,
    mul_result 
    );

    //参数定义
    parameter      A_W =   4;
    parameter      B_W =   3;
    parameter      R_W = A_W + B_W;

    //输入信号定义
    input               clk    ;
    input               rst_n  ;
    input [A_W-1:0]     mul_a  ;
    input [B_W-1:0]     mul_b  ;

    //输出信号定义
    output[R_W-1:0]     mul_result;

    //输出信号reg定义
    reg   [R_W-1:0]     mul_result;

    //中间信号定义
    reg   [R_W-1:0]     mul_result_tmp;

    //组合逻辑写法
    /*
    aaa@qq.com(*)begin
        mul_result_tmp = mul_a * mul_b;
    end


    aaa@qq.com(posedge clk or negedge rst_n)begin
        if(rst_n==1'b0)begin
            mul_result <= 0;
        end
        else begin
            mul_result <= mul_result_tmp;
        end
    end
    */
    //时序逻辑写法
   aaa@qq.com(posedge clk or negedge rst_n)begin
       if(rst_n==1'b0)begin
           mul_result <= 0;
       end
       else begin
           mul_result <= mul_a * mul_b;
       end
   end


endmodule

二、简单模块设计

(1)电路图

FPGA学习(第5节)-看电路图写出Verilog代码(乘法运算+自加一+模块实例化等)

(2)代码实现

功能分析:自加一

图中有一个加法器(组合逻辑实现)、一个D触发器(时序逻辑实现)。

module module_name(
clk    ,
rst_n  ,
//其他信号
out
);

//参数定义
parameter      DATA_W =        4;

//输入信号定义
input               clk    ;
input               rst_n  ;

//输出信号定义
output[DATA_W-1:0]  out   ;

//输出信号reg定义
reg   [DATA_W-1:0]  out   ;

//中间信号定义
reg   [DATA_W-1:0]  out_temp;

//组合逻辑写法
aaa@qq.com(*)begin
    out_temp = out+1'b1;
end

//时序逻辑写法
aaa@qq.com(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
    out<=0;
end
else begin
    out<=out_temp;
end
end

endmodule


三、复杂模块设计

FPGA学习(第5节)-看电路图写出Verilog代码(乘法运算+自加一+模块实例化等)

FPGA学习(第5节)-看电路图写出Verilog代码(乘法运算+自加一+模块实例化等)

(2)代码实现

功能分析:与运算+选择器+实例化

从输出部分开始写代码:

两个寄存器变量的D触发器(时序)--》实例化模块(带参数)--》选择器(组合)--》寄存器变量的D触发器+与运行(时序)每个模块都在一个always块里去设计

时序还是组合很清晰。

module mul2port(
    clk    ,
    rst_n  ,
    //其他信号,举例dout
    din_a  ,
    din_b  ,
    din_c  ,
    din_d  ,
    sel_a  ,
    sel_b  ,
    result_a,
    result_b
    );

    //参数定义
    parameter      A_W =     3;
    parameter      B_W =     2;
    parameter      C_W =     4;
    parameter      R_A_W =   7;
    parameter      R_B_W =   6;

    //输入信号定义
    input               clk    ;
    input               rst_n  ;
    input [A_W-1:0]     din_a  ;
    input [B_W-1:0]     din_b  ;
    input [C_W-1:0]     din_c  ;
    input [C_W-1:0]     din_d  ;
    input               sel_a  ;
    input               sel_b  ;

    //输出信号定义
    output[R_A_W-1:0]   result_a   ;
    output[R_B_W-1:0]   result_b   ;

    //输出信号reg定义
    reg   [R_A_W-1:0]   result_a   ;
    reg   [R_B_W-1:0]   result_b   ;

    //中间信号定义
    reg   [R_A_W-1:0]   result_a_tmp;
    reg   [R_B_W-1:0]   result_b_tmp;
    reg   [C_W  -1:0]   sel_dout    ;
    reg                 sel         ;

    aaa@qq.com(posedge clk or negedge rst_n)begin
        if(rst_n==1'b0)begin
            result_a <= 0;
        end
        else begin
            result_a <= result_a_tmp;
        end
    end

    aaa@qq.com(posedge clk or negedge rst_n)begin
        if(rst_n==1'b0)begin
            result_b <= 0;
        end
        else begin
            result_b <= result_b_tmp;
        end
    end

    mul_module  #(.A_W(A_W),.B_W(C_W)) mul_4_3(
                         .clk       (clk       ),
                         .rst_n     (rst_n     ),
                         .mul_a     (din_a     ),
                         .mul_b     (sel_dout  ),
                         .mul_result(result_a_tmp) );

    mul_module  #(.A_W(B_W),.B_W(C_W)) mul_4_2(
                         .clk       (clk       ),
                         .rst_n     (rst_n     ),
                         .mul_a     (din_b     ),
                         .mul_b     (sel_dout  ),
                         .mul_result(result_b_tmp) );   
    aaa@qq.com(*)begin
        if(sel)
            sel_dout = din_c;
        else
            sel_dout = din_d;
    end

    aaa@qq.com(posedge clk or negedge rst_n)begin
        if(rst_n==1'b0)begin
            sel <= 1'b0;
        end
        else begin
            sel <= sel_a && sel_b;
        end
    end

    endmodule