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

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

一、简单模块设计

(1)任务说明


(2)代码实现:

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

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




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;

    //组合逻辑写法
    /*
    always@(*)begin
        mul_result_tmp = mul_a * mul_b;
    end


    always@(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
    */
    //时序逻辑写法
   always@(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)电路图


(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;

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

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

endmodule


三、复杂模块设计



(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         ;

    always@(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

    always@(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) );   
    always@(*)begin
        if(sel)
            sel_dout = din_c;
        else
            sel_dout = din_d;
    end

    always@(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



  • 10
    点赞
  • 81
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
抱歉,我不能直接为您提供代码和仿真,因为这需要更多的细和规范,以确保生成的代码能够完全符合您的要求。 以下是一个简单的FPGA代码示例,用于将20个通道的时间数字转换成数字信号,并用Verilog语言编: ``` module time_to_digital_converter( input CLK, // 时钟信号 input [19:0] TIME_CH[0:19], // 20个时间通道的输入信号 output reg [19:0] DIG_CH[0:19] // 20个数字信号的输出 ); reg [19:0] counter[0:19]; // 用于计数的寄存器 always @(posedge CLK) begin for (int i = 0; i < 20; i = i + 1) begin if (TIME_CH[i] != 0 && counter[i] == 0) begin DIG_CH[i] <= 1; counter[i] <= TIME_CH[i]; end else if (counter[i] != 0) begin DIG_CH[i] <= 0; counter[i] <= counter[i] - 1; end end end endmodule ``` 该代码有一个时钟信号 `CLK` 以及20个时间通道的输入信号 `TIME_CH[0:19]`,每个通道都有一个计数器寄存器 `counter[0:19]`,用于计算时间数字的时间。如果输入信号 `TIME_CH` 的值不为0且计数器寄存器的值为0,则将相应的数字信号 `DIG_CH` 置为1,并将计数器寄存器设置为 `TIME_CH` 的值。一旦计数器寄存器的值不为0,则数字信号 `DIG_CH` 保持为0,并将计数器寄存器的值递减1。 为了进行仿真,您需要使用仿真工具,例如ModelSim或Xilinx ISE。您需要编一个仿真测试台,以模拟输入时间数字和时钟信号,并检查输出数字信号是否按照预期工作。 希望这可以为您提供一些帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值