0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Verilog常用基础语法全梳理

ZYNQ 来源:ZYNQ 作者:ZYNQ 2022-11-10 10:05 次阅读

	

把前面看过的夏宇闻老师的那本书上面的verilog的常用语法进行了一下梳理,并且为了熟悉语法在HDLBits刷了刷题,一些例子就直接从那个里面引用了。参考过的内容列在下面:

·verilog数字系统设计教程(夏宇闻):学习verilog的必读书。第四版的第三章到第七章,夏宇闻老师这本书上讲的比较详细。

·HDLBits:类似于CS的LeetCode,题目倒是没有LeetCode多,适合入门语法。

·Verilog Tutorial : 这个里面对verilog语法讲的很细,而且有大量的代码示例,不过代码不能直接复制下来运行,但是用一些小trick还是可以把代码搞下来的。

01verilog模块的结构

verilog语法中最基本的元素就是模块了,主要包括模块声明以及模块内容。首先是模块的声明,具体的声明结构如下

module Hello_World(<端口信号列表>); //注意这里要有分号
  <逻辑代码>
endmodule

接下来是模块内容,主要包括I/O口的说明,内部信号的说明,功能的定义三个结构。

(1)I/O口的说明

输入端口:
  input[信号位宽-1:0] 端口1;
        input[信号位宽-1:0] 端口2;
        ...
输出端口:
  output[信号位宽-1:0] 端口1;
        output[信号位宽-1:0] 端口2;
        ...
输入/输出端口:
  inout[信号位宽-1:0] 端口1;
        inout[信号位宽-1:0] 端口2;
        ...

(2)内部信号的说明

reg [width-1:0] 变量1,变量2,...;
wire[width-1:0]变量1,变量2,...;

(3)功能定义

主要有三种最基本的功能定义方法,分别是always,assign,initial。一个module里面可以写多个always,assign,initial,这些功能在电路通电之后也是同时开始执行的。

·initial用在仿真。主要有以下两种功能,一方面可以在仿真开始时对各变量进行初始化,这个初始化过程不需要任何仿真时间,即在 0 ns 时间内,便可以完成初始化工作;另一方面可以用来生成激励波形作为电路的测试仿真信号。

// 完成初始化
initial begin
  areg = 0;    //初始化一个寄存器
  for(index=0;indexindex=index+1)
    memory[index] = 0; //初始化一个memory
end
// 完成激励波形的生成
initial begin
  inputs = 8'b0000_0000;
  #10 inputs = 8'b0110_0101;
  #10 inputs = 8'b1111_0101;
end

·assign用于实现组合逻辑,直接互联不同的信号,或者变量值。

assign  = <变量或者常量>;
// 右边也可以使用 (判断条件)?(判断条件为真时的逻辑处理):(判断条件为假时的逻辑处理)
// 完成更加简洁的if...else语句

·always语句可以实现组合逻辑,也可以实现时序逻辑。它是一直运行的,但是后面跟着的过程块是否执行,就要看它的触发条件是否满足了,这个触发条件就写在括号中。可以由信号的边沿触发,也可以由信号的变化触发。

// 所有信号变换都可以触发,是组合逻辑
always@(*) begin
  ...
end
// 信号a与信号b的变化都可以触发,是组合逻辑
always@(a or b) begin
  ...
end
// 时钟的上升沿或者复位信号的下降沿可以触发,是时序逻辑
always@(posedge clk or negedge rst_n) begin
  ...
end

(4)引用模块

在引用时既可以按照模块定义的端口顺序来连接,不用标明原模块定义时规定的端口名,也可以在引用时采用“.”符号,这样就不用完全按照模块定义的端口顺序来连接了,一般还是使用“.”来引用比较好,这样逻辑比较清晰。

...
MyDesign M1(.sin(in),.pout(out));
...

MyDesign 是已经定义的另一个模块,M1是自己取的一个名字,sin与pout是MyDesign模块里面端口的名字,in与out是在正在写的模块中定义的两个信号,这两个信号分别连接到sin与pout端口。

02数据类型

数据主要可以分为两种类型,一种是常量类型的数据,另一种是变量类型的数据。

(1)常量类型的数据

·整数:二进制(b),十进制(d),十六进制(h)。

·x和z值:

·x代表未定值:不确定状态为高还是为低,旨在告诉综合工具设计者不关心它的电平是多少,是0是1都可以。

·z代表高阻值:输出引脚与内部电路断开,不导通,其电平随外部电平高低而定,表示设计者不驱动这个信号。

·一个x可以用来定义十六进制数的4位二进制数的状态或者二进制数的1位。建议在写case语句中使用这些值。

·负数:在位宽表达式前加一个减号就可以定义一个负数。

·下划线:主要用来分隔开数的表达式以提高程序的可读性,它只能用在具体的数字之间。

<位宽><进制><数字>
8'b10101100 // 位宽为8的数的二进制表示,'b表示二进制
8'ha2 // 位宽为8的数的十六进制表示,'h表示十六进制
<数字>
10 //默认采用十进制,并且数字的位宽采用默认位宽(与机器系统相关,最少32位)


4'b10x0  //位宽为4的二进制数,从低位数起第2位是不定值
8'h4x    //位宽为8的二进制数,其低四位值为不定值


-8'd5//这个表达式代表5的补数


16'b1010_1011_1111_1010

·参数:使用parameter来定义常量,注意在引用实例的时候可以通过参数的传递来改变定义时规定的参数。

//parameter可以直接定义一系列常量参数
parameter a=2,b=2.3,c=a-1;
//可以通过传参修改module中定义的parameter
module Decode(A,B);
  parameter width=1,polarity=1;
  ...
endmodule
module Decode_top;
  wire[3:0] A1;
  wire[3:0] B1;
  wire[3:0] A2;
  wire[3:0] B2;
  Decode #(4,0) D1(A1,B1); // D1实例引用的width=4,polarity=0
  Decode #(5) D2(A2,B2);   // D2实例引用的width=5,polarity=1
endmodule

(2)变量类型的数据

·wire型:常用来表示用以assign关键字指定的组合逻辑信号。verilog程序模块中输入、输出信号类型默认时自动定义为wire型。wire型信号可以用做任何方程式的输入,也可以用作assign语句的输出。

·reg型:常用来表示always模块内的指定信号,在always模块内被赋值的每一个信号都必须定义成reg型。reg的默认初始值是不定值。

·memory型:从编程角度可以理解成一个多维数组,从物理角度可以理解成RAM型存储器或者ROM存储器,从实现角度可以理解成是reg型数据的扩展。

wire [3:0] a,b; //定义了两个4位的wire型数据
reg [3:0] a,b;  //定义了两个4位的reg型数据
reg [n-1:0] memory [m-1:0] //[n-1:0]定义存储器中每一个存储单元的大小,[m-1:0]定义了
         //存储器中存储单元的个数也可以理解成各存储单元的地址
memory[3] = 0; //注意对memory中的存储单元进行读写操作的时候必须指定该单元在存储器中的地址

03运算符及表达式

·算术运算符

+  //加
-  //减
*  //乘
/  //除 
%  //求模

进行整数除法运算时结果值略去小数部分,只留下整数部分,取模运算要求%两侧均为整数。

·位运算符

~  //取反
&  //按位与
|  //按位或
^  //按位异或
~^ //按位同或

不同长度的数据在进行位运算的时候,系统会自动地将两者按右端对齐,位数少的操作数会在相应的高位用0填满。

·逻辑运算符

&& //逻辑与
|| //逻辑或
!  //逻辑非

·关系运算符

a//小于
a>b   //大于
a<=b  //小于等于
a>=b  //大于等于

·等式运算符

==  //等于
!=  //不等于

·移位运算符

a>>n  //a右移n位
a<//a左移n位

两种移位运算都用0来填补移出的空位。

·位拼接运算符

{信号1的某几位,信号2的某几位,...}
{a,b[3:0],w,3'b101}
{4{w}} //位拼接可以用来简化表达式,这样写等同于{w,w,w,w}
{b,{3{a,b}}} //这样写等同于 {b,a,b,a,b,a,b}

位拼接表达式不允许存在没有指明位数的信号。

·缩减运算符

reg [3:0] B;
reg C;
C = &B; // 相当于 C=((B[0] & B[1])&B[2])&B[3]

与之前的位运算不同,缩减运算是对单个操作数各位的逻辑操作,最终的运算结果是1位二进制数。

04条件语句及循环语句

(1)条件语句

条件语句主要有两种写法,一种是if else的写法,另一种是case的写法。

// if else 的写法
if(a==2'b00) begin
  <具体逻辑>
end
else if(a==2'b01) begin
  <具体逻辑>
end
else begin
  <具体逻辑>
end
// case 的写法
case(a)
  2'b00:<具体逻辑>
  2'b01:<具体逻辑>
  default:<具体逻辑>
endcase

还有用法与case类似的casex与casez,这两者可以用来处理比较过程中不必考虑的情况。其中casez语句用来处理不必考虑高阻值z的比较过程,casex语句则将高阻值z和不定值都视为不必关心的情况。所谓不必关心的情况就是说,在表达式进行比较时不将该位的状态考虑在内。

(2)循环语句

总体来说循环语句用到的不是很多,这里就列举两个最常用的forever和for循环。

·forever循环语句常用来产生周期性的波形,用来作为仿真信号,必须要写在initial块中。

·for循环语句的一般形式是for(<变量名>=<初值>;<判断表达式>;<变量名>=<新值>)。for可以综合的,for几次就相当于把你的电路复制几次。

initial begin
   clk = 0;
   forever begin
       clk = ~clk;
       #5;
   end
end


initial begin
    counter2 = 'b0 ;
    for (i=0; i<=10; i=i+1) begin
        #10 ;
        counter2 = counter2 + 1'b1 ;
    end
end

05块语句

·顺序块:采用begin end语句,块内的语句是按照顺序执行的,前面的语句执行完才轮到后面的语句执行,每条语句的延迟时间是相对于前一条语句的仿真时间定的。

·并行块:采用fork join语句,块内的语句是并行执行的,每条语句的延迟时间是相对于程序进入块内的时间。并行块是不可综合的,只能用在仿真中。

module begin_tb();
  reg [7:0] r;
regclk;


  initial begin:begin_tb //这里可以将块名写上
     clk = 0;
     #50 r = 8'h35;
     #30 r = 8'h12;
     #40 r = 8'h41;
  end
  always #5 clk = ~clk;
endmodule


module fork_tb();
  reg [7:0] r;
  reg clk;


  initial fork:fork_tb //这里可以将块名写上
     clk = 0;
     #50 r = 8'h35;
     #30 r = 8'h12;
     #40 r = 8'h41;
  join
  always #5 clk = ~clk;
endmodule

00a27846-6090-11ed-8abf-dac502259ad0.png

00bc1c60-6090-11ed-8abf-dac502259ad0.png

上面是begin end的仿真时序图,下面是fork join的仿真时序图。从仿真时序图中可以明显的看到,begin end是串行的时序而fork join是并行的时序。

·生成块:采用generate endgenerate语句,这一声明语句方便参数化模块的生成。当对矢量中的多个位进行重复操作时,或者当进行多个模块的实例引用的重复操作时,或者在根据参数的定义来确定程序中是都应该包括某段verilog代码的时候,使用生成语句能够大大简化程序的编写过程。

1、for:在generate中的应用主要是用来减少重复操作。

//-------------module-------------//
// 顶层模块包含N个半加器
module top(a,b,sum,cout);
  parameter N=2;
  input  [N-1:0] a, b;
  output  [N-1:0] sum, cout;


  // 声明一个暂时的循环变量
  genvar i;


  // 生成N次
  generate
    for (i = 0; i < N; i = i + 1) begin
          half_add u0(a[i], b[i], sum[i], cout[i]);
    end
  endgenerate
endmodule


// 定义一个半加器
module half_add(a, b, sum, cout);
  input a,b;
  output sum,cout;


  assign sum  = a ^ b;
  assign cout = a & b;
endmodule
//-------------testbench-------------//
`timescale 1ns / 1ns
module top_tb;
  parameter N = 2;
  reg  [N-1:0] a, b;
  wire [N-1:0] sum, cout;


  top instance1( .a(a), .b(b), .sum(sum), .cout(cout));


  initial begin
    a <= 0;
b<=0;


    #10 a <= 'h2;
      b <= 'h3;
    #20 b <= 'h4;
    #10 a <= 'h5;
  end
endmodule

00c86ace-6090-11ed-8abf-dac502259ad0.jpg

00dc3ad6-6090-11ed-8abf-dac502259ad0.jpg

具体生成的RTL图以及仿真结果如上图所示。

2、if:在generate中主要用来根据参数的定义来确定程序。

//-------------module-------------//
module top(a, b, sel, out);
  input a,b,sel;
  output out;
  parameter USE_CASE = 0;
  // 使用 generate 块选择使用 mux_case 或者 mux_assign
  generate
    if (USE_CASE)
      mux_case m1 (.a(a), .b(b), .sel(sel), .out(out));
    else
      mux_assign m2 (.a(a), .b(b), .sel(sel), .out(out));
  endgenerate


endmodule
// Design #1: 使用assign
module mux_assign ( input a, b, sel,
                   output out);
  assign out = sel ? a : b;
  // 这个display可以在仿真时标明在用哪一个design
  initial
    $display ("mux_assign is instantiated");
endmodule




// Design #2: 使用case
module mux_case (input a, b, sel,
                 output reg out);
  always @ (a or b or sel) begin
    case (sel)
      0 : out = a;
        1 : out = b;
    endcase
  end
  // 这个display可以在仿真时标明在用哪一个design
  initial
    $display ("mux_case is instantiated");
endmodule
//-------------testbench-------------//
`timescale 1ns / 1ns
module top_tb;
  reg a, b, sel;
  wire out;
  integer i;
  // 使用 USE_CASE 选择用哪个 design
  initial 
  $display("USE_CASE = %0d",0);
  top #(.USE_CASE(0)) u0 ( .a(a), .b(b), .sel(sel), .out(out));


  initial begin
    a <= 0;
    b <= 0;
    sel <= 0;


    for (i = 0; i <= 2; i = i + 1) begin
      #10 a <= $random;
          b <= $random;
          sel <= $random;
      $display ("i=%0d a=0x%0h b=0x%0h sel=0x%0h out=0x%0h", i, a, b, sel, out);
    end
  end
endmodule

00f61500-6090-11ed-8abf-dac502259ad0.jpg

上面是仿真结果在tcl的输出,可以看到使用不同的USE_CASE可以选取不同的design。

3、case:在generate中主要用来根据参数的定义来确定程序。

//-------------module-------------//
module top (a, b, cin, sum, cout);
  input a,b,cin;
  output sum,cout;
  
  parameter ADDER_TYPE = 1;


  generate
    case(ADDER_TYPE)
      0 : ha u0 (.a(a), .b(b), .sum(sum), .cout(cout));
      1 : fa u1 (.a(a), .b(b), .cin(cin), .sum(sum), .cout(cout));
    endcase
  endgenerate
endmodule
// Design #1: 半加器
module ha (input a, b,
           output reg sum, cout);
  always @ (a or b)
  {cout, sum} = a + b;


  initial
    $display ("Half adder instantiation");
endmodule


// Design #2: 全加器
module fa (input a, b, cin,
           output reg sum, cout);
  always @ (a or b or cin)
  {cout, sum} = a + b + cin;


    initial
      $display ("Full adder instantiation");
endmodule


//-------------testbench-------------//
`timescale 1ns / 1ns
module top_tb;
  reg a, b, cin;
  wire sum, cout;


  initial 
  $display("ADDER_TYPE = %0d",0);
  top #(.ADDER_TYPE(0)) u0 (.a(a), .b(b), .cin(cin), .sum(sum), .cout(cout));


  initial begin
    a <= 0;
    b <= 0;
    cin <= 0;


    $monitor("a=0x%0h b=0x%0h cin=0x%0h cout=0%0h sum=0x%0h",
             a, b, cin, cout, sum);


    for (int i = 0; i<=2; i = i + 1) begin
    #10 a <= $random;
    b <= $random;
    cin <= $random;
    end
  end
endmodule

011cf864-6090-11ed-8abf-dac502259ad0.jpg

上面是仿真结果在tcl的输出,可以看到使用不同的ADDER_TYPE可以选取不同的design。

06任务

任务要写在task endtask中,有点像matlab中函数这个概念,其中可以有input、output、inout端口作为出入口参数。注意任务中不能出现initial语句和always语句, 但任务调用语句可以在initial语句和always语句中使用(这些都是对static task来说的,automatic task略有不同,一般默认是static task)。

module top_tb;


reg [7:0] x, y, z;


 task sum;
  input  [7:0] a, b;
  output [7:0] c;
  begin
    c = a + b;
  end
endtask




initial begin:test
    {x,y} = {8'd2,8'd3}; 
    sum (x, y, z);
    #10 {x,y} = {8'd5,8'd1};
    sum (x, y, z);
end


endmodule

x 和 y 是输入值,最后计算结果存储在 z 中。

012e1d56-6090-11ed-8abf-dac502259ad0.jpg

07常用的系统任务

(1)格式化输出函数

·$display

reg [3:0] rval;
initial begin
    rval = 3;
    $display("rval = %h hex, rval = %d decimal, rval = %b binary", rval, rval, rval);
    $display("current scope is %m"); // 输出等级层次的名字
    $display("%s", "Hello World");   
     //在%和表示输出格式的字符之间插入一个0自动调整显示输出的数据宽度  
    $display("Simulation time is %0d", $time);
end

013c1e92-6090-11ed-8abf-dac502259ad0.jpg

·$strobe

与display不同,它可以确保所有在同一时钟沿赋值的其它语句在执行完毕之后才显示数据。

reg [3:0] a,b;
wire [4:0] y = a + b;
// 采用display的方式输出
initial begin
    a = 3;
    b = 2;
    $display("$display: time =%0d, a= %d, b=%d, y= %d ",$time ,a, b, y);
    #10
    a = 4;
    $display("$display: time =%0d, a= %d, b=%d, y= %d ",$time,a, b, y);
    b = 5;
    $display("$display: time =%0d, a= %d, b=%d, y= %d ",$time ,a, b, y);
    #10;
end
// 采用strobe的方式输出
initial begin
    a = 3;
    b = 2;
    $strobe("$strobe: time =%0d, a= %d, b=%d, y= %d ",$time ,a, b, y);
    #10
    a = 4;
    $strobe("$strobe: time =%0d, a= %d, b=%d, y= %d ",$time,a, b, y);
    b = 5;
    $strobe("$strobe: time =%0d, a= %d, b=%d, y= %d ",$time ,a, b, y);
    #10;
end

015573ce-6090-11ed-8abf-dac502259ad0.png

从上面演示的例子可以看出,当打印输出连续赋值语句或module例化的输出结果时,在当前的时间点内,$display无法输出当前运算结果,但 $strobe却可以显示组合逻辑结果。因此, 如果希望在当前时间点内打印连续赋值语句或module例化的输出结果推荐使用$strobe, 而其他情况下使用$display可以显示更多的细节。

·$monitor

一般在initial块中调用,可以不间断地对所设定的信号进行监视。一般与时间度量系统函数$time一起使用,具体的应用实例在下面时间度量系统函数给出。

(2)时间度量系统函数

·$time

该函数可以返回一个64位整数来表示当前的仿真时刻,该时刻受时间尺度比例的影响,例如在下面的例子中,时间尺度是10ns,16ns与32ns就要变成1.6与3.2,同时因为$time的输出要是整数,因此实际的输出为2和3。

`timescale 10ns / 1ns
module top_tb ();
 
reg set;
initial begin
  $monitor("time=%0d",$time," ","set=",set);
  #1.6 set = 0;
  #1.6 set = 1;
end
endmodule

016b0b80-6090-11ed-8abf-dac502259ad0.png

(3)仿真暂停与退出函数

·$finish

该系统函数可以退出仿真器,返回主操作系统结束仿真过程,并且可以输出当前的仿真时刻和位置。

01777d98-6090-11ed-8abf-dac502259ad0.png

01857baa-6090-11ed-8abf-dac502259ad0.png

·$stop

该系统函数暂停模拟并将模拟器置于交互模式。

(4)文件读取到寄存器函数

·readmemh

$readmemh("<数据文件名>",<存储器名>);
$readmemh("<数据文件名>",<存储器名>,<起始地址>);
$readmemh("<数据文件名>",<存储器名>,<起始地址>,<终止地址>);

·<数据文件名> 是指向一个文本文件,用来保存仿真的数据。每一行代表一个十六进制的数据。

·<存储器名> 为仿真文件中例化的存储器的名称。

·<起始地址>,<终止地址> 指示将文本文件中的数据存储到存储器的位置段。

`timescale 1ns / 1ps
module top_tb();   
reg clk = 0;
always clk = #10 ~clk;
reg [7:0] ram[0:127];
localparam FILE_NAME = "../../../led_sim.sim";
initial begin
    $readmemh (FILE_NAME, ram, 2, 8); //从第二个16进制数据读起,但是由于ram是8位的因此每次存入8
end
integer i;
initial
begin
    #20;
    for(i = 0; i < 16; i = i + 1)
        $display("ram[%02d] = 0x%h ", i, ram[ i ] );
    #8000;
    $stop;
end
    
endmodule

01bb73d6-6090-11ed-8abf-dac502259ad0.jpg

上图左边是文件中的数据,右边是仿真中的输出值,可以看到ram[00],ram[01],ram[09]-ram[15]的值都是0xxx(未初始化的值),真正初始化的只有ram[02]- ram[08]。

(5)随机数生成函数

·$random

一般用法是$random%b,其中b>0,它给出了一个范围在(-b+1):(b-1)中的随机数。也可以通过位拼接操作{$random}%b,生成0:(b-1)之间的随机数。

reg [23:0] rand;
rand = $random%60; // 生成一个范围在 [-59,59] 之间的随机数
rand = {$random}%60;// 生成一个范围在 [0,59] 之间的随机数

08编译预处理

·宏定义 `define

`define WORDSIZE 8
module
reg [`WORDSIZE-1:0] data; //相当于定义[7:0],注意在引用时也要加`
...
endmodule

·文件包含 `include

`include相当于将被引用的文件全部囊括进引用文件中。可以将一些常用的宏定义命令或任务(task)组成一个文件,然后用`include命令将这些宏定义包含到自己所写的源文件中。

·时间尺度 `timescale

该命令的格式如下:`timescale<时间单位>/<时间精度>,时间单位参量用来定义模块中仿真时间和延迟时间的基准单位,时间精度参量用来定义该模块仿真时间的精确程度。

`timescale 10ns/1ns
parameter d = 1.55;
#d //时间单位为10ns,时间精度为1ns,1.55*10=15.5,再根据精度得到16,因此#d实际上是延时16ns

审核编辑 :李倩


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 模块
    +关注

    关注

    7

    文章

    2654

    浏览量

    47278
  • 仿真
    +关注

    关注

    50

    文章

    4014

    浏览量

    133310
  • Verilog
    +关注

    关注

    28

    文章

    1341

    浏览量

    109910

原文标题:Verilog常用基础语法全梳理

文章出处:【微信号:ZYNQ,微信公众号:ZYNQ】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Verilog硬件描述语言参考手册

    一. 关于 IEEE 1364 标准二. Verilog简介三. 语法总结四. 编写Verilog HDL源代码的标准五. 设计流程
    发表于 11-04 10:12 0次下载

    Verilog语法中运算符的用法

    verilog语法中使用以下两个运算符可以简化我们的位选择代码。
    的头像 发表于 10-25 15:17 169次阅读
    <b class='flag-5'>Verilog</b><b class='flag-5'>语法</b>中运算符的用法

    Verilog HDL的基础知识

    本文继续介绍Verilog HDL基础知识,重点介绍赋值语句、阻塞与非阻塞、循环语句、同步与异步、函数与任务语法知识。
    的头像 发表于 10-24 15:00 125次阅读
    <b class='flag-5'>Verilog</b> HDL的基础知识

    TestStand表达式中常用语法规则和运算符使用

    TestStand也有自己的语言嘛?在回答这个问题之前大家可以想一下在使用TestStand时有一个和语言密切相关的属性。没错那就是表达式(Expressions),在这篇文章中,小编将以Q&A的方式来带着大家来理解并熟悉TestStand表达式中较为常用的一些语法规则以
    的头像 发表于 08-15 18:10 920次阅读
    TestStand表达式中<b class='flag-5'>常用</b>的<b class='flag-5'>语法</b>规则和运算符使用

    FPGA学习笔记---基本语法

    Verilog语法是指硬件能够实现的语法。它的子集很小。常用的RTL语法结构如下: 1、模块声明:module ... end module
    发表于 06-23 14:58

    Verilog到VHDL转换的经验与技巧总结

    Verilog与VHDL语法是互通且相互对应的,如何查看二者对同一硬件结构的描述,可以借助EDA工具,如Vivado,打开Vivado后它里面的语言模板后,也可以对比查看Verilog和VHDL之间的差异。
    的头像 发表于 04-28 17:47 2068次阅读
    <b class='flag-5'>Verilog</b>到VHDL转换的经验与技巧总结

    有什么好用的verilog HDL编辑工具可用?

    有什么好用的verilog HDL编辑工具可用?最好能集成实时的verilog HDL语法检测、自定义模块识别触发等功能,最好能够免费;
    发表于 04-28 11:00

    fpga是用c语言还是verilog

    FPGA(现场可编程逻辑门阵列)开发主要使用的编程语言是硬件描述语言(HDL),其中Verilog是最常用的编程语言之一。而C语言通常用于传统的软件编程,与FPGA的硬件编程有所区别。
    的头像 发表于 03-27 14:38 1652次阅读

    verilog双向端口的使用

    输出信号。本文将详细介绍Verilog双向端口的使用,并提供示例说明其在实际应用中的作用。 第一部分:双向端口的定义和语法Verilog中,可以使用wire声明一个双向端口。例如:wire bidirectional_por
    的头像 发表于 02-23 10:18 1201次阅读

    verilog中repeat必须用begin和end吗

    Verilog中,repeat语句不需要使用begin和end块。repeat语句是一种循环控制语句,允许重复执行一个代码块指定的次数。它的一般语法如下: repeat (n) statement
    的头像 发表于 02-23 10:14 1019次阅读

    verilog如何调用其他module

    第一部分:简介 1.1 什么是Verilog模块? 在Verilog中,模块是其设计层次结构的基本单元。模块是一个用于实现特定功能的单独的硬件单元。它可以是一个组合逻辑电路,也可以是一个时序逻辑电路
    的头像 发表于 02-22 15:56 5024次阅读

    verilog task和function区别

    verilog中的task和function都是用于实现模块中的可重复的功能,并且可以接收参数和返回结果。但是它们在编写和使用上有一些区别。下面将详细介绍task和function的区别。 语法
    的头像 发表于 02-22 15:53 937次阅读

    verilog function函数的用法

    Verilog 是一种硬件描述语言 (HDL),主要用于描述数字电子电路的行为和结构。在 Verilog 中,函数 (Function) 是一种用于执行特定任务并返回一个值的可重用代码块。函数在
    的头像 发表于 02-22 15:49 4739次阅读

    oracle的update语法

    Oracle是一种强大的关系型数据库管理系统,具有广泛的应用,UPDATE语句是用于修改数据库中现有记录的重要操作之一。在本文中,我们将详细介绍Oracle的UPDATE语法及其用法。 首先,我们
    的头像 发表于 12-05 16:22 2224次阅读

    select语句的基本语法

    SELECT语句是SQL(Structured Query Language,结构化查询语言)中的一种查询语句,用于从数据库中检索数据。它是数据库操作中最常用和基本的语句之一。在本文中,我将为您详尽
    的头像 发表于 11-17 16:23 1779次阅读