Verilog基本语法(三)建模

门级建模

wire out1, in1, in2;

// 与门(and)和或门(or)
and a1(out1, in1, in2); // 与门
nand na1(out1, in1, in2); // 与非门
or or1(out1, in1, in2); // 或门
nor nor1(out1, in1, in2); // 或非门
xor x1(out1, in1, in2); // 异或门
xnor nx1(out1, in1, in2); // 同或门

// 缓冲器和非门
buf b1(out1, in1); // 缓冲器
not n1(out1, in1); // 非门

数据流建模

wire out1;
assign out1 = in1 & in2;

assign addr [15:0] = addr1_bits[15:0] ^ addr2_bits[15:0];

assign {c_out, sum[3:0]} = a[3:0] + b[3:0] + c_in;

// 隐式赋值
wire out2 = in1 & in2;

行为级建模

reg clock, reset, x, y;
integer count;
reg [15:0] reg_a, reg_b;

结构化过程语句

initial // initial块从仿真0时刻开始执行,在整个仿真过程中只执行一次。
begin // 如果块内只包含一条语句,不需要使用begin...end。
    // TODO
end

always // always块从仿真0时刻开始执行,并且循环往复地执行块中的语句。
    #10 clock = ~clock;

赋值语句

// =:阻塞式赋值语句
x = 1'b0; 
reg_a = 16'b0; // 向量初始化。
reg_a [15:13] = {1'b0,1'b0,1'b0};

// <=:非阻塞式赋值语句
reg_a [2] <= 1'b1;
reg_a [3] <= #15 1'b1; // 带延迟的位选赋值。
x <= 1'b1; 
y <= 0;
y <= @(negedge clock) x ^ y;

时序控制

// 时序控制
parameter latency = 20;
parameter delta = 2;

initial begin
    #10 y = 1'b0;
    #latency x = 1'b0;
    #(latency+delta) x = 1'b0;
end

@(clock) x = 1'b0; // 只要clock的值改变,就执行x=1语句。
@(posedge clock) x = 1'b0; // 只要clock的值发生正向跳变,就执行x=1。
@(negedge clock) x = 1'b0; // 只要clock的值发生负向跳变,就执行x=1。
x = @(posedge clock) 1'b0; // 立即赋值,在clock的值发生正向跳变时刻赋值给x。

// or事件控制
always @(clock or reset) begin // 等待clock或reset输入信号的改变,这里or也可以用“,”代替。
// always @(clock, reset) begin 
    // TODO
end

// @*操作符的使用
always @(*) // @(*)把所有输入变量都包括进敏感列表。
begin
    // TODO
end

条件控制与多路分支语句

// 条件语句
if (clock)
    x = 1'b0;
else 
    y = 1'b1;

// 多路分支语句
case  (x)
    2'b00: y = 1'b0;
    2'b01: y = 1'b1;
    2'b10, 2'b11: begin
        y = 1'b0;
        y = 1'b1;
    end
endcase

循环语句

// 循环语句
initial begin
    while (count < 10) // while 循环
        count = count + 1;

    for (count = 0; count < 10; count = count + 1) // for 循环
        $display("Count = %d", count);

    repeat (10); // repeat 循环,此例为循环10次。
end

顺序块和并行块

顺序块和并行块的区别:当控制转移到块语句的时刻,并行块中所有的语句同时开始执行,语句之间的先后顺序是无关紧要的。

// 顺序块
begin : block1 // 名字为block1的顺序命名块。
integer i; // 整型变量i是block1命名块的静态本地变量,可以通过层次名top.block1.i被其他模块访问。
    //TODO
end

// 并行块
fork
    x = 1'b0;
    #5 y = 1'b1;
join

 

posted @ 2023-01-23 13:04  vicky2021  阅读(124)  评论(0编辑  收藏  举报