Verilog HDL Modelsim Acknowledgment This slides is revised

  • Slides: 77
Download presentation
Verilog HDL 及Modelsim仿真 范益波

Verilog HDL 及Modelsim仿真 范益波

Acknowledgment • This slides is revised from “Verilog HDL基 础语法入门” by夏宇闻

Acknowledgment • This slides is revised from “Verilog HDL基 础语法入门” by夏宇闻

什么是verilog • Verilog是一种硬件设计语言(Hardware Description Language, HDL) • 主要用于数字逻辑电路设计 • 跟VHDL类似

什么是verilog • Verilog是一种硬件设计语言(Hardware Description Language, HDL) • 主要用于数字逻辑电路设计 • 跟VHDL类似

举例1 例[2. 1. 1]: module adder ( count, sum, a, b, cin ); input

举例1 例[2. 1. 1]: module adder ( count, sum, a, b, cin ); input [2: 0] a, b; //声明输出信号equal input cin; //声明输入信号 output count; output [2: 0] sum; assign {count, sum}=a+b+cin; endmodule 这个例子描述了一个三位的加法器。从例子中可以看 出整个Verilog HDL程序是嵌套在module和endmodule 声明语句里的。

举例3 例[2. 1. 3]: module trist 1(out, in, enable); output out; input in, enable;

举例3 例[2. 1. 3]: module trist 1(out, in, enable); output out; input in, enable; mytri tri_inst(out, in, enable); endmodule mytri(out, in, enable); output out; input in, enable; assign out = enable? In : 'bz; endmodule 上述程序例子通过另一种方法描述了一个三态门。 在这个例子中存在着两个模块:模块trist 1调用模块 mytri 的实 例元件。通过这种结构性模块构造可构成特大型模块。

如何描述激励信号 module t; reg a, b, sel; wire out; //引用多路器实例 mux 2 m (out,

如何描述激励信号 module t; reg a, b, sel; wire out; //引用多路器实例 mux 2 m (out, a, b, sel); //加入激励信号 initial begin a=0; b=1; sel=0; #10 b=1; sel=1; #10 a=1; #10 $stop; endmodule

仿真 具简介 • Mentor公司的Modle. Sim – Learn from the ‘help’ manual of the software

仿真 具简介 • Mentor公司的Modle. Sim – Learn from the ‘help’ manual of the software – Learn from some teaching books • Cadence的NC-Verilog • Synopsys的VCS

举例说明数据类型的选择 模块DUT的边界 module top; wire y; reg a, b; DUT u 1(y, a, b);

举例说明数据类型的选择 模块DUT的边界 module top; wire y; reg a, b; DUT u 1(y, a, b); initial begin a = 0; b = 0; #10 a =1; …. endmodule net/register net 输入口 net/register 输出口 net 输出/入口 module DUT(Y, A, B_); output Y; input A, B: wire Y, A, B; and (Y, A, B); endmodule net inout

主要的数据类型:parameters § § § 常用参数来声明运行时的常数。 可用字符串表示的任何地方, 都可以用定义的参数来代替。 参数是本地的,其定义只在本模块内有效。 举例说明: module md 1(out, in 1,

主要的数据类型:parameters § § § 常用参数来声明运行时的常数。 可用字符串表示的任何地方, 都可以用定义的参数来代替。 参数是本地的,其定义只在本模块内有效。 举例说明: module md 1(out, in 1, in 2); …. . parameter cycle=20, prop_del=3, setup=cycle/2 -prop_del, p 1=8, x_word=16’bx, file = “/user 1/jmdong/design/mem_file. dat”; wire [p 1: 0] w 1; //用参数来说明wire 的位宽 …. initial begin $open(file); ……. #20000 display(“%s”, file); $stop end …. endmodule

语法详细讲解 简单 ROM 建模 `timescale 1 ns/10 ps module myrom(read_data, addr, read_en_); input read_en_;

语法详细讲解 简单 ROM 建模 `timescale 1 ns/10 ps module myrom(read_data, addr, read_en_); input read_en_; input [3: 0] addr; output [3: 0] read_data; reg [3: 0] mem [0: 15]; initial $readmemb(“my_rom_data”, mem); always @ (addr or read_en_) if(!read_en_) read_data=mem[addr]; endmodule ROM的数据存储 在另外的一个独 立的文件中 my_rom_data 0000 0101 1100 0011 1101 0010 0011 1111 1000 1001 1000 0001 1101 1010 0001 1101

语法详细讲解 简单RAM建模 `timescale 1 ns/1 ns module mymem(data, addr, read, write); inout [3: 0]

语法详细讲解 简单RAM建模 `timescale 1 ns/1 ns module mymem(data, addr, read, write); inout [3: 0] data; inout [3: 0] addr; input read, write; reg [3: 0] memory [0: 15]; //4 bits, 16 words //从存储器读出到总线上 assign data=read? memory[addr]: 4’bz; //从总线写入存储器 always @ (posedge write) memory[addr]=data; endmodule

语法详细讲解 存储量可变的只读存储器建模 例: module scalable_ROM (mem_word, address); parameter addr_bits=8; //size of address bus parameter

语法详细讲解 存储量可变的只读存储器建模 例: module scalable_ROM (mem_word, address); parameter addr_bits=8; //size of address bus parameter wordsize=8; //width of a word parameter words=(1<<addr_bits); //size of mem output [wordsize: 1] mem_word; input [addr_bits: 1] address; //word of memory //address bus reg [wordsize: 1] mem [0 : words-1]; //mem declaration //output one word of memory wire [wordsize: 1] mem_word=mem[address]; endmodule

语法详细讲解 双向口建模 使用连续赋值为双向口建模: en_a_b b 1 bus_a bus_b b 2 en_b_a module bus_xcvr (bus_a,

语法详细讲解 双向口建模 使用连续赋值为双向口建模: en_a_b b 1 bus_a bus_b b 2 en_b_a module bus_xcvr (bus_a, bus_b, en_a_b, en_b_a); inout bus_a, bus_b; input en_a_b, en_b_a; assign bus_b=en_a_b? bus_a: ’bz; assign bus_a=en_b_a? bus_b: ’bz; //结构模块逻辑 endmodule 当en_a_b=1时,bus_a的 值传到bus_b上 当en_b_a=1时,bus_b的 值传到bus_a上 控制信号 en_a_b 和 en_b_a 在时间上分开

有限状态机 datain = 0 module exp(out, datain, clk, rst); input clk, rst, datain; output

有限状态机 datain = 0 module exp(out, datain, clk, rst); input clk, rst, datain; output out; reg out; 状态变量 reg state; 0 always @(posedge clk or posedge rst) if(rst) {state, out}=2’b 00; else datain = 1 case语句 case(state) 1’b 0: begin out=1’b 0; 1 if(!datain) state=1’b 0; clk rst else state=1’b 1; end 1’b 1 begin 0 11 01 识别 11序列 out=datain; 转到下一个状态 state=1’b 0; end default: {state, out}=2’b 00; 默认状态指针 endcase endmodule out

同步寄存器示例1 在下面的例子中,rega 仅用作临时存储器,因此在综合时它将被优化掉。 module ex 1 reg(d, clk, q); input d, clk; output q;

同步寄存器示例1 在下面的例子中,rega 仅用作临时存储器,因此在综合时它将被优化掉。 module ex 1 reg(d, clk, q); input d, clk; output q; reg q, rega; always @(posedge clk) begin rega = 0; if(d) rega = 1; q = rega; endmodule

组合寄存器示例1 y和rega 不断被赋新值(因为语句中有else rega = 0; ),综合出的电路是一 个纯组合逻辑。 rega 是临时变量,在综合中会被优化掉。 module ex 3 reg(y,

组合寄存器示例1 y和rega 不断被赋新值(因为语句中有else rega = 0; ),综合出的电路是一 个纯组合逻辑。 rega 是临时变量,在综合中会被优化掉。 module ex 3 reg(y, a, b, c); input a, b, c; output y; reg y, rega; always @(a or b or c) begin if(a&b) rega=c; else rega=0; y=rega; endmodule

完整的电平敏感列表 module sens(q, a, b, sl); input a, b, sl; output q; reg q;

完整的电平敏感列表 module sens(q, a, b, sl); input a, b, sl; output q; reg q; always @(sl or a or b) begin if(!sl) q=a; else q=b; endmodule

case条件语句 module comcase(a, b, c, d, e); input a, b, c, d; output e;

case条件语句 module comcase(a, b, c, d, e); input a, b, c, d; output e; reg e; always @(a or b or c or d) case ({a, b}) 2’b 11: e=d; 2’b 10: e=~c; 2’b 01: e=1’b 0; 2’b 00: e=1’b 1; endcase endmodule

if条件语句 module compif(a, b, c, d, e); input a, b, c, d; output e;

if条件语句 module compif(a, b, c, d, e); input a, b, c, d; output e; reg e; always @(a or b or c or d) if(a&b) e=d; else if (a&~b) e=~c; else if (~ a&b) e=1’b 0; else if (~a&~b) e=1’b 1; endmodule

不完整条件语句 2 module incpif(a, b, c, d, e); input a, b, c, d; output

不完整条件语句 2 module incpif(a, b, c, d, e); input a, b, c, d; output e; reg e; always @(a or b or c or d) if (a&b) e=d; else if(a&~b) e=~c; endmodule

带有缺省项的完整条件语句 module compif(a, b, c, d, e); input a, b, c, d; output e;

带有缺省项的完整条件语句 module compif(a, b, c, d, e); input a, b, c, d; output e; reg e; always @(a or b or c or d) if (a&b) e=d; else if (a&~b) e=~c; else e=‘bx; endmodule

复位建模 复位是可综合风格代码的重要组成部分,通常在有限状态机中使用复 位建模。 同步复位: module sync(q, ck, r, d); input ck, d, r; output

复位建模 复位是可综合风格代码的重要组成部分,通常在有限状态机中使用复 位建模。 同步复位: module sync(q, ck, r, d); input ck, d, r; output q; reg q; always @(negedge ck) if(r) q<=0; else q<=d; endmodule 同步块中的异步复位: module async(q, ck, r, d); input ck, d, r; output q; reg q; always @(negedge ck or posedge r) if(r) q<=0; else q<=d; endmodule

锁存器复位 下面的例子演示了更加复杂的复位建模。其中的敏感列表是完全的, 因为这是一个锁存器。 module latch(q, enable, set, clr, d); input enable, d, set, clr;

锁存器复位 下面的例子演示了更加复杂的复位建模。其中的敏感列表是完全的, 因为这是一个锁存器。 module latch(q, enable, set, clr, d); input enable, d, set, clr; output q; reg q; always @(enable or set or clr or d) begin if(set) q<=1; else if (clr) q<=0; else if (enable) q<=d; endmodule