基于SparkRoad的《Verilog数字系统设计教程·第三版(夏宇闻)》学习(6)——第5章

思考题:

网上好的总结
9.注意是在测试环节,所以使用了initial,而always不可以使用

10.声明一个名为oscillate的寄存器变量并将它初始化为0,使其每30个时间单位进行一次取反操作,使用forever循环。

reg oscillate;
initial begin
    oscillate = 0;
    forever
        #30 oscillate = ~oscillate;
end

11.设计一个周期为40个时间单位的时钟信号,其占空比为25%。使用always和initial块进行设计,将其在仿真0时刻的值初始化为0。

initial begin
    clk = 0;
    always begin
        #30 clk = ~clk;
        #10 clk = ~clk;
    end
end

14.d的最终值为?

initial begin
    b = 1'b1;
    c = 1'b0;
    #10 b = 1'b0;
end
​
initial begin
    d = #25 (b | c);
end

d = 1'b0。等于是在10单位后,b成为0,然后在和c或,0和0或,得出d = 1'b0。

15.使用带有同步清零端的D触发器(清零端高电平有效,在时钟下降沿执行清零操作)设计一个下降沿触发的D触发器,只能使用行为语句(D触发器的输出q应当声明为寄存器变量)。使用设计出的D触发器输出一个周期为10个时间单位的时钟信号。

module dff_syn(d, clk, clr, q);
    input       d, clk, clr;
    output reg  q;
​
    always @(negedge clk)
        if (clr)    q <= 0;
        else        q <= d;
endmodule
​
//testbench
`timescale 1ns/1ns
module dff_syn_tb();
reg     d, clk, clr;
wire    q;
initial begin
    d   = 0;
    clr = 0;
    clk = 0;
​
    #10 clr = 1;
    #20 clr = 0;
    forever
        #5 d = ~d;
end
dff_syn u1(d, clk, clr, q);
always #5 clk = ~clk;
endmodule

16.使用带有异步清零端的D触发器设计第15题中要求的D触发器(在清零端变为高电平后立即执行清零操作,无须等待下一个时钟下降沿),并对这个D触发器进行测试。

module dff_asyn(d, clk, clr, q);
    input       d, clk, clr;
    output  reg q;
​
    always @(negedge clk, posedge clr) begin
        if (clr)    q <= 0;
        else        q <= d;
    end
endmodule
​
//testbench
`timescale 1ns/1ns
module dff_asyn_tb();
reg     d, clk, clr;
wire    q;
initial fork
    d   = 0;
    clr = 0;
    clk = 0;
​
    #10 clr = 1;
    #20 clr = 0;
    forever
        #5 d = ~d;
join
dff_asyn u1(d, clk, clr, q);
always #5 clk = ~clk;
endmodule

17.使用wait语句设计一个电平敏感的锁存器,该锁存器的输入信号为d和clock,输出为q,其功能是当clock=1时q=d。

module L_FF(d, clock, q);
    input       d, clock;
    output  reg q;
    always @(*) begin
        wait(clock)
            q = d;
    end
endmodule

wait语句说明
wait语句:
wait语句是一种不可综合的电平触发事件控制语句,有如下两种形式:
wait(条件表达式) 语句/语句块;
wait(条件表达式);
对于第一种形式,语句块可以是串行块(begin…end)或并行块(fork…join)。当逻辑表达式为“真”时,语句块立即得到执行;否则,暂停进程并等待,直到逻辑表达式变为“真”,再开始执行。
对于第二种形式,当仿真执行到wait语句时,如果条件表达式为真,那么立即结束该语句的执行,仿真程序继续往下执行;否则,仿真程序进入等待状态,直到条件表达式为真。

18.使用条件语句设计四选一多路选择器。

module mux4_to_1(out, i0, i1, i2, i3, s1, s0);
output  reg out;
input       i0, i1, i2, i3;
input       s1, s0;
always @(*) begin
    if (s1==0 && s0==0)         out = i0;
    else if (s1==0 && s0==1)    out = i1;
    else if (s1==1 && s0==0)    out = i2;
    else if (s1==1 && s0==1)    out = i3;
    else                        out = 1'bx;
end
endmodule

20.使用while循环设计一个时钟信号发生器。其时钟信号的初值为0,周期为10个时间单位。

initial begin
    clk = 0;
    while(1)    #5 clk = ~clk;
end

22.使用forever循环设计一个时钟信号,周期为10,占空比为40%,初值为0。

initial begin
    clk = 0;
    forever begin
        #6 clk = ~clk;
        #4 clk = ~clk;
    end
end

23.使用repeat将语句a=a+1延迟20个时钟上升沿之后再执行。

parameter delay = 20;
reg a;
begin
    repeat(delay)
        @(posedge clk);
    a = a + 1;
end

这个有点没看懂,repeat下面再来一个@什么意思

反思:

1.网表Netlist
在电路设计中,网表(netlist)是用于描述电路元件相互之间连接关系的,一般来说是一个遵循某种比较简单的标记语法的文本文件。
对于复杂的集成电路设计,电路功能需要通过多个级别的描述来完成。
门级、RYL级、行为级

posted @ 2023-05-23 18:44  江左子固  阅读(50)  评论(0编辑  收藏  举报