Verilog通过文件去定义管脚?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Verilog通过文件去定义管脚?相关的知识,希望对你有一定的参考价值。

之前在哔哩哔哩看到一个老师讲解Verilog如何通过文件去定义管脚,但当时没有收藏,现在去找找不到了,希望哪位能指点下。谢谢

FPGA管脚分配文件保存方法

  使用别人的工程时,有时找不到他的管脚文件,但可以把他已经绑定好的管脚保存下来,输出到文件里。

方法一:

  查看引脚绑定情况,quartus -> assignment -> Pins,打开FPGA引脚界面,在这个界面的菜单中可以保存引脚文件为csv格式(表格形式)和tcl格式。

步骤:File -> Export… -> 选择保存名字和保存格式。

方法二:

  直接输出管脚配置,assignmengt -> Export assignmengt,可以保存配置为qsf格式,该格式可以用记事本查看,在该文件中同样包含了引脚信息。注意:保存时会在原工程文件夹下新建一个文件夹。

  至于元件的其它配置方式,可以在qsf文件和tcl文件中用语句来设置,也可以在Assignment -> device,界面中设置。

加载:

  使用已经有的引脚文件时,在选项assignment -> Import assignment,中可以选择要加载的引脚文件。此时,可以加载qsf 和 csv(或txt)文件。

保存的csv(txt)文件、qsf文件 和 tcl文件的区别:

csv(txt)文件:包含芯片所有管脚信息,包括分配的和未分配的;

qsf文件:包含管脚分配信息和芯片信息;

tcl文件:只包含已分配管脚信息。

 

最后总结最重要的一点,就是没有使用的IO一定要进行状态的定义:

Assignment >> Device >>选择Device and pins  options >> unusedpin >>设置为Tri-stated(软件设置有很多种可以选择),再次重新编译和下载,其他没有用到的IO就不会出现其他不可预料的状况了(我之前没设置就导致使用开发板时,明明没定义的数码管IO却把所有的都点亮了>=<)。

宏定义 `define

 

用一个指定的标识符(即名字)来代表一个字符串,它的一般形式为:

 

`define 标识符(宏名) 字符串(宏内容)

 

如:`define signal string

 

它的作用是指定用标识符signal来代替string这个字符串,在编译预处理时,把程序中在该命令以后所有的signal都替换成string。这种方法使用户能以一个简单的名字代替一个长的字符串,也可以用一个有含义的名字来代替没有含义的数字和符号,因此把这个标识符(名字)称为“宏名”,在编译预处理时将宏名替换成字符串的过程称为“宏展开”。`define是宏定义命令。

 

[例1]:`define  WORDSIZE 8

module

reg[1:`WORDSIZE]  data; //这相当于定义 reg[1:8] data;

 

关于宏定义的八点说明:

 

1)       宏名可以用大写字母表示,也可以用小写字母表示。建议使用大写字母,以与变量名相区别。

2)       `define命令可以出现在模块定义里面,也可以出现在模块定义外面。宏名的有效范围为定义命令之后到原文件结束。通常,`define命令写在模块定义的外面,作为程序的一部分,在此程序内有效。

3)      在引用已定义的宏名时,必须在宏名的前面加上符号“`”,表示该名字是一个经过宏定义的名字。

4)       使用宏名代替一个字符串,可以减少程序中重复书写某些字符串的工作量。而且记住一个宏名要比记住一个无规律的字符串容易,这样在读程序时能立即知道它的含义,当需要改变某一个变量时,可以只改变 `define命令行,一改全改。如例1中,先定义WORDSIZE代表常量8,这时寄存器data是一个8位的寄存器。如果需要改变寄存器的大小,只需把该命令行改为:`define WORDSIZE 16。这样寄存器data则变为一个16位的寄存器。由此可见使用宏定义,可以提高程序的可移植性和可读性。

5)       宏定义是用宏名代替一个字符串,也就是作简单的置换,不作语法检查。预处理时照样代入,不管含义是否正确。只有在编译已被宏展开后的源程序时才报错。

6)       宏定义不是Verilog HDL语句,不必在行末加分号。如果加了分号会连分号一起进行置换。如:

[例2]:module  test;

  reg  a, b, c, d, e, out;

 `define  expression  a+b+c+d;

assign out = `expression + e;

  ...

    endmodule

 

经过宏展开以后,该语句为:

assign  out = a+b+c+d;+e;

显然出现语法错误。

7)       在进行宏定义时,可以引用已定义的宏名,可以层层置换。如:

[例3]:module test;

reg  a, b, c;

wire out;

`define aa a + b

`define cc c + `aa

assign out = `cc;

    endmodule

这样经过宏展开以后,assign语句为

assign  out = c + a + b;

8)       宏名和宏内容必须在同一行中进行声明。如果在宏内容中包含有注释行,注释行不会作为被置换的内容。如:

 

[例4]: module

        `define typ_nand nand #5  //define a nand with typical delay

     `typ_nand g121(q21,n10,n11);

        ………

        endmodule

 

经过宏展开以后,该语句为:

 

nand #5 g121(q21,n10,n11);

 

宏内容可以是空格,在这种情况下,宏内容被定义为空的。当引用这个宏名时,不会有内容被置换。

 

注意:组成宏内容的字符串不能够被以下的语句记号分隔开的。

    注释行

    数字

    字符串

    确认符

    关键词

    双目和三目字符运算符

    如下面的宏定义声明和引用是非法的。

    `define  first_half  "start of string

    $display(`first_half end of string");

    注意在使用宏定义时要注意以下情况:

    1)       对于某些 EDA软件,在编写源程序时,如使用和预处理命令名相同的宏名会发生冲突,因此建议不要使用和预处理命令名相同的宏名。

    2)       宏名可以是普通的标识符(变量名)。例如signal_name 和 'signal_name的意义是不同的。但是这样容易引起混淆,建议不要这样使用。

参考技术A 是不可以的。
编写的VERILOG语言只是描述了该模块的功能,如果要分配相应的管脚,首先要在建立工程时选择合适的芯片型号。
然后,在verilog编写完成,全编译通过后,通过tools-pin assignments菜单进行相应的管脚分配。
欢迎追问~

Verilog - 将多个定义连接成一个定义

【中文标题】Verilog - 将多个定义连接成一个定义【英文标题】:Verilog - Concatenate multiple defines into one define 【发布时间】:2017-01-27 21:59:54 【问题描述】:

我正在寻找一种连接多个define statements into a singledefine 语句的方法,以便我可以在case 语句中使用它。

例如,具有在头文件中定义的内存地址。我有一个 case 语句,根据地址决定是否应该将值写入 LUTRAM 或块 ram。

我有以下定义:

`define PWM_REPEAT_REG                      (6'h10)         // Number of times to repeat a PWM Pulse
`define PWM_WIDTH_REG                       (6'h14)         // Pulse width in timebase counts
`define PWM_PULSE_PERIOD                    (6'h1c)         // PWM pulse period in timebase counts.

在我的代码中,我有一个看起来像这样的 case 语句:

case(sys_mgr_address) 
    `PWM_REPEAT_REG, `PWM_WIDTH_REG, `PWM_PULSE_PERIOD : begin // Values for block RAM
        ram_a_din               <= sys_mgr_write_data;
        ram_a_addr              <= sys_mgr_address;
        ram_a_wr_enable         <= 1'b1;
        sys_mgr_write_ok        <= 1'b1;
        update_available        <= 1'b1; 
    end 
endcase

实际的设计有几个地址,这种case语句会重复多次。我不想为每个定义一遍又一遍地输入所有定义,我想创建另一个看起来像这样的定义:

`define PWM_MODULE_BLOCK_RAM_ADDRESSES (`PWM_REPEAT_REG, `PWM_WIDTH_REG, `PWM_PULSE_PERIOD)

    case(sys_mgr_address) 
    PWM_MODULE_BLOCK_RAM_ADDRESSES : begin // Values for block RAM
        ram_a_din               <= sys_mgr_write_data;
        ram_a_addr              <= sys_mgr_address;
        ram_a_wr_enable         <= 1'b1;
        sys_mgr_write_ok        <= 1'b1;
        update_available        <= 1'b1; 
    end 
endcase

^^ 上面的代码不起作用,因为它将数字连接成一个非常大的向量。我尝试了一些变体,比如没有连接大括号 ,将其定义为文本,一些不同的 `` 变体(但我不确定它到底是做什么的)。

有什么方法可以在编译前查看扩展的宏吗?现在,对于我尝试过的大多数错误,它只是给我一个错误,这并不能使故障排除变得容易。

谢谢!

【问题讨论】:

【参考方案1】:

你想太多了。所有你需要做的就是把逗号的宏

`define PWM_MODULE_BLOCK_RAM_ADDRESSES `PWM_REPEAT_REG, `PWM_WIDTH_REG, `PWM_PULSE_PERIOD 

定义宏只是文本的简单扩展。

【讨论】:

我实际上首先尝试过,但在定义周围使用了括号,所以它是PWM_MODULE_BLOCK_RAM_ADDRESSES (PWM_REPEAT_REG,PWM_WIDTH_REG, PWM_PULSE_PERIOD)`。您没有括号的方法有效,为什么会这样? 因为括号不是 case 语句项的合法语法。宏必须扩展为合法的语法。 谢谢,一切都清楚了!现在完美运行。

以上是关于Verilog通过文件去定义管脚?的主要内容,如果未能解决你的问题,请参考以下文章

FPGA教程案例61硬件开发板调试1——初识FPGA开发板,通过verilog控制LED灯,按键开关等

verilog中如何将wire类型的变量A 与reg类型的变量B进行比较?

ZYNQ从入门到秃头05 LED闪烁实验 && 按键控制LED实验Verilog(PL)

FPGA作为从机与STM32进行SPI协议通信---Verilog实现

Verilog定义计算位宽的函数clogb2

请问在FPGA Verilog设计中,使用关键字parameter定义常数有什么好处?