查看: 1338|回复: 0

[评测分享] 【ALINX&紫光同创PGL12G开发板】-2-对VerilogHDL代码的入门理解

[复制链接]
  • TA的每日心情
    无聊
    2022-4-28 09:50
  • 签到天数: 443 天

    连续签到: 1 天

    [LV.9]以坛为家II

    发表于 2020-8-25 00:42:03 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 独活草 于 2020-8-25 15:32 编辑

      大概花了2天,静下心来去尝试理解PGL12G开发板官方提供的前三个实验的VerilogHDL代码,同时结合下载程序后板子的实际运行效果,尝试调整参数验证猜测;竟然取得一点成果,现将代码全注释给大家分享一下:***************************************************************************************************
    实验1:流水灯
    `timescale 1ns / 1ps   //一般用在VerilogHDL编程最开始声明的地方,意思单位时间为1ns,精度为1ps
                       //如果后面要用到延时,#d 可以直接调用这个时间:#3就是延时3ns的意思
    module led_test
    (            
      sys_clk,        // 系统时钟50Mhz
      rst_n,         //复位按钮,低电平有效           
      led           // LED状态寄存器
    );
    //输入输出端口申明
    input        sys_clk;
    input        rst_n;
    output [3:0]    led;
    reg [31:0]      timer; //定义32位的计数器
    reg [3:0]       led;  //定义4位LED状态寄存器
    //0~ 49_999_999 1秒
    //0~ 99_999_999 2秒
    //0~149_999_999 3秒
    //0~199_999_999 4秒

    always@(posedge sys_clk or negedge rst_n) //每个时钟周期或者复位信号产生时
    begin
        if (~rst_n)//复位按钮松开时是高电平,按下时是低电平,此处取反
            timer <= 32'd0;//复位时,把32位计数器清0
        else if (timer == 32'd199_999_999)
              timer <= 32'd0;//计数到第四秒,把32位计数器清0,重新计数
        else
              timer <= timer + 1'b1;//计数器做 +1 运算;
    end

    // LED control
    always@(posedge sys_clk or negedge rst_n) //每个时钟周期或者复位信号产生时
    begin
        if (~rst_n)
            led <= 4'b0000;//复位时,把4个LED置为低电平,点亮4个LED灯
        else if (timer == 32'd49_999_999)
            led <= 4'b0001; //计数到第1秒时,LED1熄灭;
        else if (timer == 32'd99_999_999)
            led <= 4'b0010; //计数到第2秒时,LED2熄灭;
        else if (timer == 32'd149_999_999)
            led <= 4'b0100; //计数到第3秒时,LED3熄灭;
        else if (timer == 32'd199_999_999)
            led <= 4'b1000;//计数到第4秒时,LED4熄灭;
    end
    endmodule
    ***************************************************************************************************
    实验2:按键
    module key_test
    (
    input            sys_clk,         //系统时钟 50Mhz
    input [3:0]        key_in,         //按健,按下时为低电平,松开时高电平,默认为高电平
    output[3:0]        led            //LED 低电平时点亮
    );                     
    reg[3:0] led_r;          //定义第1阶段D锁存器
    reg[3:0] led_r1;         //定义第2阶段D锁存器
    always@(posedge sys_clk )//每个时钟周期
    begin     
        led_r <= ~key_in;     //第1阶段锁存数据
    end                        
    always@(posedge sys_clk )
    begin
        led_r1 <= led_r;      //第2阶段锁存数据
    end
    assign led = led_r1;   //assign表示连续赋值,且被赋值的变量只能是wire型的
    endmodule

    //wire 表示直通,只要输入有变化,输出马上无条件地反映;reg 表示一定要有触发,输出才会响应输入
    //reg 型变量,赋值只能在always块内部赋值;
    //wire 使用在连续赋值语句中,reg使用在过程赋值语句中;默认类型
    //wire 只能被assign连续赋值,reg只能在initial和always块内部赋值;
    ***************************************************************************************************
    将实验2的代码改为下面可以实现同样的效果:
    module key_test
    (
    input               sys_clk,      
    input [3:0]           key_in,      
    output[3:0]           led        
    );
    assign led = ~key_in; //赋值                                                
    endmodule
    ***************************************************************************************************
    实验3:PLL
    module pll_test
    (
    input      sys_clk,                    //系统时钟50Mhz
    input      rst_n,                      //复位按钮,低电平有效         
    output     clk_out                     //倍频或分频 输出的时钟信号 J9_Pin3
    );
    wire      locked;    //wire表示直通,只要输入有变化,输出马上无条件地反映

    /////////////////////PLL IP 核调用////////////////////////////
    clk_wiz_0 clk_wiz_0_inst         //实例化clk_wiz_0
    .clkin1    (sys_clk),          // 50Mhz系统时钟导入
    // 时钟信号输出端口
    .clkout0    (      ),         // OUT 200Mhz
    .clkout1    (      ),         // OUT 100Mhz
    .clkout2    (      ),         // OUT 50Mhz
    .clkout3    (clk_out  ),         // OUT 25Mhz         
    //控制信号         
    .pll_rst    (~rst_n  ),         // 复位
    .pll_lock   (locked  )             // 锁住频率
    );               
    endmodule
    ***************************************************************************************************
      通过最近两天的学习,我大概理解 VerilogHDL 语言编程的目的是为了对一个具有输入输出的黑箱,其要实现某个运算目的而进行逻辑设计;
    1、编程风格大概是先在 module 中申明定义好要用到的资源:输入、输出、IP核、中间变量(寄存器等);
    2、然后编写在每个时钟周期或者复位信号产生时//always@(posedge sys_clk or negedge rst_n) 要进行的初始化或其他赋值操作;
    3、实现运算的逻辑结构简单,常用的就是if-else;case(类似switch-case);
    4、调用开发环境平台具有的一些IP核,需要多花时间去研究哪些私有变量是一定要赋值的。









    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-4-20 08:02 , Processed in 0.116651 second(s), 16 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.