需要使用的软件:
module example( input wire sys_rst_n,//输入信号 inout wire sda,//输入输出信号,基本不用 output wire po_flag // 输出信号 ); // 只有输入信号是不能直接得到输出信号的 // 需要通过一些数据和参数对输入信号进行处理,得到输出信号 // 一般需要对输入信号进行处理之后得到输出信号 // 线网型变量 -- wire可以被看作是物理连接 -- 被综合成物理连线 wire [0:0] flag; // 寄存器型变量 -- 具有对某一时间点的状态进行保持的功能 // 可综合电路中被综合成寄存器 reg [7:0] cnt; // 参数的定义 // parameter 可以在顶层模块通过实例化对参数进行修改 parameter CNT_MAX = 100; //localparam -- 只用在模块内部,不能在实例化的时候进行修改 localparam CNT_MAX = 100; // 模块的实例化 example #( .CNT_MAX (8'd100) // 实例化时参数可以修改 ) example_inst ( .sys_clk (sys_clk), .sys_rst_n (sys_rst_n), .po_flag (po_flag) ); /* 常量 表示方法: [换算为二进制数之后的位宽]'[进制符号][与数值对应的进制数] 8'd171 d -- 十进制 b -- 二进制 h -- 十六进制 不写位宽 -- verilog会自动进行匹配 总位宽大于实际位宽,自动补0,总位宽小于实际位宽,则自动截断左边超出的位数 d'7 8'd7 -- 8'b0000_0111 前面补5个0 2'd7 换算位二进制是 2'b11 (7换成二进制是111),总长度位2位,所以截掉左侧的部分 直接写参数 100 ,表示位宽为32bit的十进制数100 */ // 赋值方式 // 阻塞赋值 = // 阻塞赋值可以看作是顺序执行,每条语句执行完成之后才能执行下一条语句 a = 1; b = 2; c = 3; begin a = b; c = a; end a = 2; b = 2; c = 2; // 非阻塞赋值 <= 并行执行 a = 1; b = 2; c = 3; begin a <= b; // 同一时刻,这两条语句是同时执行的 c <= a; end a = 2; b = 2; c = 1; // always语句 always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) cnt <= 8'b0; // 进行寄存器复位 else if (cnt == CNT_MAX) // 寄存器中的值记到最大的时候,维持最大值 cnt <= CNT_MAX; else cnt <= cnt + 8'd1; // 每个周期都加1 // assign语句 assign po_flag = (cnt == CNT_MAX) ? 1'b1 : 1'b0; endmoudle
+ - * -- 一般不用 / -- 一般不用 % -- 求余数,两边都为整型数据
// & 作为单目运算符,&m,将m的所有bit相与,得到结果是1bit 4'b1111 = 1&1&1&1 = 1'b1 4'b1101 = 1&1&0&1 = 1'b0 // & 作为双目运算符表示按位与,m&n,是将m的每个bit与n的每个bit相与,在运算的时候保证m和n的bit数相等,最后结果位数和m(n)的bit数相等 4'b1010&4'b0101 = 4'b0000
a = 4'ha b = 4'd0 c = a && b // c的值为0
a < b a > b a <= b a >= b
b <= a << 1; // a的每一位都左移一位,结果赋值给b b <= a >> 1; // a的没一位都右移一位,结果赋值给b
4'b1000 >> 3; // 4'b0001 4'b1000 >> 4; // 4'b0000
a = 8'b1011_1111; b = 3'b011; c = 5'b11011; {a,b,c} ; // 拼接成16bit
[表达式1]?表达式2:表达式3 a = 6; b = 7; c = (a>b)?a:b;
if(表达式) // 这种写法在always语句块产生组合逻辑的时候中会产生latch,不推荐使用 语句块; if(表达式) 语句块1; else if(表达式2) 语句块2; .... else 语句; // 这种是最常用的写法
switch(表达式) case value1 : 语句1; case value2 : 语句2; .... default: 语句;
`timescale 1ns/1ns // 时间尺度预编译指令 时间单位/时间精度 时间单位和时间精度有由1,10及100以及s,ms,ns,us,ps,fs组成 时间单位:定义仿真过程中所有与时间相关量的单位 仿真中使用#数字表示延迟相应的时间单位的时间,例如#10表示延时10个时间单位,即10ns 时间精度:决定时间相关量的精度及仿真显示的最小单位 `timescale 1ns/10ps // 精度0.01, #10.11 表示延迟10110ps `timescale 100ps/1ns // 错误,时间单位不能比时间精度小
// 主要的函数,在支持verilog语法的编译器中都会显示为高亮的关键字 $display //打印信息,自动换行 $write //打印信息 $strobe //打印信息,自动换行,最后执行 $monitor //检测变量 $stop //暂停仿真 $finish //结束仿真 $time //时间函数 $random //随机函数 $readmemb //读取文件的函数
$display(); // 输出,打印信息 $display("%b+%b = %d",a,b,c); // %d %D -- 十进制 // %o %O -- 八进制 // %b %B -- 二进制 // %d %D -- 十六进制 // 不指定进制,默认为十进制数
`timescale 1ns/1ns module tb_test(); reg [3:0] a; reg [3:0] b; reg [3:0] c; // initial只在仿真中使用,是不可综合的 // 仿真开始,只执行一次 initial begin $display("Hello"); $display("EmbedFire"); a = 4'd5; b = 4'd6; c = a + b; #100; $display("%b + %b = %d",a,b,c); end endmodule result: Hello EmbedFire 010 + 0110 = 11
`timescale 1ns/1ns module tb_test(); reg [3:0] a; reg [3:0] b; reg [3:0] c; // initial只在仿真中使用,是不可综合的 // 仿真开始,只执行一次 initial begin $write("Hello"); $write("EmbedFire"); a = 4'd5; b = 4'd6; c = a + b; #100; $write("%b + %b = %d",a,b,c); end endmodule
`timescale 1ns/1ns module tb_test(); reg [3:0] a; reg [3:0] b; reg [3:0] c; // initial只在仿真中使用,是不可综合的 // 仿真开始,只执行一次 initial begin $strobe("strobe:Hello"); // 写在最前面,但是执行在最后 a = 4'd5; $display("EmbedFire"); $display("display:%b + %b = %d",a,b,c); // 在执行这条语句的时候b,c都没有进行赋值 // 所以b,c未知的x b = 4'd6; c = a + b; #100; end endmodule
`timescale 1ns/1ns module tb_test(); reg [3:0] a; reg [3:0] b; reg [3:0] c; initial begin a = 4'd5; #100; b = 4'd6; #100; c = a + b; end initial begin $monitor("%b + %b = %d",a,b,c); end endmodule
`timescale 1ns/1ns module tb_test(); initial begin $display("hello"); $display("EmbedFire"); #100; $display("Stop Simulation"); $stop; #100; $display("Finish Simulation"); $finish; // 结束仿真 end endmodule
`timescale 1ns/1ns module tb_test(); reg [3:0] a; always #10 a = $random; initial $monitor("a = %d @time %d",a,$time); endmodule
$readmemb("数据文件名",存储器名); $readmemh("数据文件名",存储器名);
`timescale 1ns/1ns module tb_test(); integer i; reg [7:0] a [20:0]; // a 为宽度为8bit,深度为21bit的存储器 initial begin $readmemb("EmbedFire.txt",a); for(i = 0;i<=20;i=i+1) begin #10; $write("%s",a[i]); // Welcome to EmbedFire! end end endmodule
读取的文件