我是靠谱客的博主 勤恳楼房,最近开发中收集的这篇文章主要介绍FPGA学习笔记:verilog基础代码与modelsim仿真(二),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

补充组合逻辑电路实现:全加器

原理图:

在这里插入图片描述

使用两个半加器组成全加器,第一个半加器的输入in_1、in_2作为全加器的输入,同时in_1作为第二个半加器的输入;

第二个半加器的输入2作为全加器的进位cin;

将半加器1与半加器2的进位输出用或门连接作为全加器的进位输出,半加器2的求和输出作为全加器的求和输出。



verilog代码实现功能:

 module full_adder(
    
    input   wire    in_1,
    input   wire    in_2,
    input   wire    cin,
    
    output  wire    sum,
    output  wire    count
    
    
 );
 wire  h0_sum;
 wire  h0_count;
 wire  h1_count;
 half_adder  half_adder_inst0
(
     
    
    .in_1  (in_1 ) ,
    .in_2  (in_2 ) ,
    .sum   (h0_sum)  ,
    .count (h0_count)
   
);



 half_adder  half_adder_inst1
(
    
    
    .in_1  ( cin) ,
    .in_2  ( h0_sum) ,
    .sum   (sum)  ,
    .count ( h1_count)
   
);
 
 assign count = (h0_count | h1_count);
 
 
 endmodule

其中,需要用到半加器的功能实例化,半加器的代码具体参考上一篇文章: https://blog.csdn.net/qq_52899124/article/details/128219813



仿真逻辑文件:

 `timescale 1ns/1ns
 module tb_full_adder();
 
 reg in_1;
 reg in_2;
 reg cin;
 
 wire sum;
 wire  count;
 
 initial
    begin
        in_1  <= 1'b0;
        in_2 <= 1'b0;
        cin  <= 1'b0;
    end
 
 
 initial 
    begin
        $timeformat(-9,0,"ns",6);
        $monitor("@time %t :in_1=%b,in_2=%b,cin=%b,sum=%b,count=%b" ,$time,in_1,in_2,cin,sum,count);
    end
    
    
always #10 in_1 <= {$random} % 2;
always #10 in_2 <= {$random} % 2;
always #10 cin <= {$random} % 2;


full_adder  full_adder_inst
(
        .in_1(in_1)   ,
        .in_2(in_2)   ,
        .cin  (cin )    ,
           
        .sum  (sum )  ,
        .count(count)
);
    
endmodule




modelsim仿真波形图:

在这里插入图片描述










时序逻辑电路

D触发器:

波形图及原理图:

在这里插入图片描述

verilog代码:
 module flip_flop(
    
  input   wire  sys_clk ,   //50Mhz
  input   wire  sys_rst_n ,   
  input   wire  key_in  ,
  
  output  reg   led_out
    

    
    
 );        
        
//Asynchronous reset
 
always@(posedge  sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        led_out <= 1'b0;
    else
        led_out  <=  key_in; 

 
endmodule

上述采用异步清零的方式实现功能。若采用同步清零,代码应为:

 module flip_flop(
    
  input   wire  sys_clk ,   //50Mhz
  input   wire  sys_rst_n ,   
  input   wire  key_in  ,
  
  output  reg   led_out
    
 );
 
 //Synchronous reset
always@(posedge  sys_clk )
    if(sys_rst_n == 1'b0)
        led_out <= 1'b0;
    else
        led_out  <=  key_in;
        
        

 
endmodule



仿真逻辑代码:
  `timescale 1ns/1ns
  module tb_flip_flop();
  
  reg sys_clk;
  reg sys_rst_n;
  reg key_in;
  
  wire led_out;

  
initial
    begin
        sys_clk = 1'b1;
        sys_rst_n <= 1'b0;
        key_in <= 1'b0;
        #20         //delay 20ns
        sys_rst_n   <= 1'b1;
        #210
        sys_rst_n <= 1'b0; 
        sys_rst_n   <= 1'b1;

    end
  
 always #10 sys_clk =~sys_clk;
 
 always #20 key_in <= {$random} % 2;    //input signal period should be greater than or equal to the clock period
 
 initial 
     begin
         $timeformat(-9,0,"ns",6);
         $monitor("@time %t :key_in=%b,led_out=%b" ,$time,key_in,led_out);
     end
     
     


 
 
 flip_flop  flip_flop_inst
 (
         .sys_clk(sys_clk)   ,
         .key_in(key_in)   ,
         .sys_rst_n (sys_rst_n)    ,
            
         .led_out  (led_out)  
         
 );
     
 endmodule
 
 
 


modelsim仿真波形图:

在这里插入图片描述






模M计数器——实现led灯闪烁

值得一提,模M的计算方式:
M = t / T M = t / T M=t/T
M:计数器模值 t:自定义时间周期 T:时钟周期(时钟频率的倒数)

波形图及原理图:

在这里插入图片描述

在这里插入图片描述

上述波形使用计数器全模值完成LED灯闪烁,耗费资源过多,可使用计数器一半模值使保持LED亮或灭,计数器计数达到一半模值后跳转到由0重新开始计数且LED灯状态取反即可实现。



verilog代码实现:

 module counter
 #(
     
   parameter    CNT_MAX = 25'd24_999_999
     
)
(
    input   wire    sys_clk     ,
    input   wire    sys_rst_n   ,
    
    output reg  led_out
);

reg     [24:0]  cnt;
reg             cnt_flag;
always@(posedge sys_clk or negedge sys_rst_n)
    
    if(sys_rst_n == 1'b0)
        cnt <=  25'd0;
    else    if(cnt == CNT_MAX)
        
        cnt <=  25'd0;
    else
        cnt <=  cnt +   25'd1;
        
always@(posedge sys_clk or negedge sys_rst_n)
    
    if(sys_rst_n == 1'b0)
        cnt_flag <= 1'b0;
    else    if(cnt == (CNT_MAX-25'd1))
        
        cnt_flag <=  1'b1;
    else
        cnt_flag <= 1'b0;
    
   
    
always@(posedge sys_clk or negedge sys_rst_n)
 
    if(sys_rst_n == 1'b0)
        led_out <=  1'b0;
        
    else if(cnt == CNT_MAX)
        led_out <= ~led_out;
    else
        led_out<= led_out;
    

  
endmodule
 


方法2 使用cnt_flag作为中间变量

波形图:

在这里插入图片描述

当计数器达到模值一半时,cnt_flag获得一个高脉冲,当cnt_flag取高脉冲时,leg_out状态曲反;

verilog代码实现仿真

 module counter
 #(
     
   parameter    CNT_MAX = 25'd24_999_999
     
)
(
    input   wire    sys_clk     ,
    input   wire    sys_rst_n   ,
    
    output reg  led_out
);

reg     [24:0]  cnt;
reg             cnt_flag;
always@(posedge sys_clk or negedge sys_rst_n)
    
    if(sys_rst_n == 1'b0)
        cnt <=  25'd0;
    else    if(cnt == CNT_MAX)
        
        cnt <=  25'd0;
    else
        cnt <=  cnt +   25'd1;
        
always@(posedge sys_clk or negedge sys_rst_n)
    
    if(sys_rst_n == 1'b0)
        cnt_flag <= 1'b0;
    else    if(cnt == (CNT_MAX-25'd1))
        
        cnt_flag <=  1'b1;
    else
        cnt_flag <= 1'b0;
    
   



always@(posedge sys_clk or negedge sys_rst_n)
    
    if(sys_rst_n == 1'b0)
        led_out<= 1'b0;
    else   if(cnt_flag == 1'b1)
        
        led_out <= ~led_out;
    else
        led_out <= led_out;
    

        
  
  
endmodule
 


仿真代码:

  `timescale 1ns/1ns
 module tb_counter();
  
 reg sys_clk ;
 reg sys_rst_n ;

  
 wire  led_out;
  
 initial
     begin
         sys_clk  <= 1'b1;
         sys_rst_n<= 1'b0;
         #20
         sys_rst_n <= 1'b1;
         
     end
  
  
initial 
     begin
         $timeformat(-9,0,"ns",6);
         $monitor("@time %t :sys_rst_n=%b,led_out=%b" ,$time,sys_rst_n,led_out);
     end
     
     
 always #10 sys_clk <= ~sys_clk;  //50HZ

 
 
 counter  
 #(
    .CNT_MAX(25'd24)  //Pass of parameters
 )counter_inst
 (
         .sys_clk(sys_clk)     ,
         .sys_rst_n(sys_rst_n)   ,   
         .led_out(led_out)
 );
     
 endmodule
 
 
 



方法一modelsim仿真波形图:

在这里插入图片描述

在这里插入图片描述






方法二modelsim仿真波形图:

在这里插入图片描述

在这里插入图片描述

最后

以上就是勤恳楼房为你收集整理的FPGA学习笔记:verilog基础代码与modelsim仿真(二)的全部内容,希望文章能够帮你解决FPGA学习笔记:verilog基础代码与modelsim仿真(二)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(48)

评论列表共有 0 条评论

立即
投稿
返回
顶部