Dff

这一节终于开始时序电路了。首先是一个用的最多的D触发器。

module top_module (    input clk,    // Clocks are used in sequential circuits    input d,    output reg q );//    // Use a clocked always block    //   copy d to q at every positive edge of clk    //   Clocked always blocks should use non-blocking assignments    always@(posedge clk)    begin       q <= d;     endendmodule

Dff8

8位D触发器,写法和上一题是一样的。

module top_module (    input clk,    input [7:0] d,    output [7:0] q);    always@(posedge clk)    begin        q <= d;    endendmodule

Dff8r

带同步高电平复位的D触发器。

module top_module (    input clk,    input reset,            // Synchronous reset    input [7:0] d,    output [7:0] q);    always@(posedge clk)    begin        if(reset)            q <= 'd0;           else            q <= d;    endendmodule

Dff8p

注意这道题触发器是下降沿触发。

module top_module (    input clk,    input reset,    input [7:0] d,    output [7:0] q);    always@(negedge clk)    begin        if(reset)            q <= 'h34;        else            q <= d;            endendmodule

Dff8ar

这道题是异步复位,把areset写在敏感事件列表即可。

module top_module (    input clk,    input areset,   // active high asynchronous reset    input [7:0] d,    output [7:0] q);    always@(posedge clk or posedge areset)    begin        if(areset)            q <= 'd0;        else            q <= d;    endendmodule

Dff16e

这题多了一个字节使能信号,只有对应的字节使能才能写入,否则维持当前的值。

module top_module (    input clk,    input resetn,    input [1:0] byteena,    input [15:0] d,    output [15:0] q);    always@(posedge clk)    begin        if(~resetn)            q <= 'd0;        else            q <= {byteena[1]?d[15:8]:q[15:8],byteena[0]?d[7:0]:q[7:0]};            endendmodule

Exams/m2014 q4a

这题要求使用一个latch,latch是电平触发的触发器,当ena信号为高电平时输入会传递给输出,这样的缺点是毛刺(glitch)会逐级传递,所以应尽量避免综合出不必要的latch,这一点在前面if和case语句中提到过。

提示中告诉了这里应该使用非阻塞赋值,因为其仍然是时序电路。

module top_module (    input d,     input ena,    output q);    always@(*)    begin        if(ena)            q<=d;    endendmodule

Exams/m2014 q4b

module top_module (    input clk,    input d,     input ar,   // asynchronous reset    output q);    always@(posedge clk or posedge ar)    begin        if(ar)            q <= 'd0;        else            q <= d;    endendmodule

Exams/m2014 q4c

总放些重复的题有点浪费时间。。。

module top_module (    input clk,    input d,     input r,   // synchronous reset    output q);    always@(posedge clk)    begin        if(r)            q <= 'd0;        else            q <= d;    endendmodule

Exams/m2014 q4d

module top_module (    input clk,    input in,     output out);    always@(posedge clk)    begin        out <= in^out;    endendmodule

Mt2015 muxdff

这道题只要写出一个子模块即可。

module top_module (    input clk,    input L,    input r_in,    input q_in,    output reg Q);    always@(posedge clk)    begin        Q <= L?r_in:q_in;    endendmodule

Exams/2014 q4a

同样也是写一个子模块。

module top_module (    input clk,    input w, R, E, L,    output Q);    always@(posedge clk)    begin        Q <= L?R:(E?w:Q);    endendmodule

Exams/ece241 2014 q4

根据RTL视图直接写代码就可以了。

module top_module (    input clk,    input x,    output z);     reg [2:0]Q=3'd0;    always@(posedge clk)    begin        Q[0] <= x^Q[0];        Q[1] <= x&~Q[1];        Q[2] <= x|~Q[2];    end    assign z=~|Q;endmodule

Exams/ece241 2013 q7

使用verilog实现一个JK触发器。

module top_module (    input clk,    input j,    input k,    output reg Q);     always@(posedge clk)    begin        case({j,k})            2'b00:Q<=Q;            2'b01:Q<=1'b0;            2'b10:Q<=1'b1;            2'b11:Q<=~Q;        endcase    endendmodule

Edgedetect

用了两个always,其实和答案是一样的。

module top_module (    input clk,    input [7:0] in,    output reg[7:0] pedge);    reg [7:0] in_r;    always@(posedge clk)    begin        in_r <= in;    end    always@(posedge clk)    pedge <= in&~in_r;endmodule

Edgedetect2

和上一题思路是一样的,区别是逻辑改为异或。

module top_module (    input clk,    input [7:0] in,    output reg[7:0] anyedge);    reg [7:0] in_r;    always@(posedge clk)    begin           in_r <= in;        anyedge <= in_r^in;    endendmodule

Edgecapture

capture和detect区别:capture会保持1,直到reset。

out <= (~in&in_r)|out;代表只有1会传递到out,从而达到保持的作用。

module top_module (    input clk,    input reset,    input [31:0] in,    output reg[31:0] out);    reg [31:0] in_r;    always@(posedge clk)    begin        in_r <= in;        if(reset)            out <= 'd0;        else if(~in&in_r)            out <= (~in&in_r)|out;    endendmodule

Dualedge

要求写一个双边沿触发器,题目已经告诉了@(posedge clk or negedge clk)的写法是不被允许的。

这题确实没想到好的方法,我的写法可能会产生毛刺,因为在边沿的时候q_p和q_n需要时间跳变,这个时候输出就可能有问题,当然,这样仿真还是能通过的,但实际电路中不能这样写。

题目给的答案非常巧妙,上升沿时p变为d^n,所以输出q = (p^n) = (d^n^n) = d,下降沿同理。

我的答案:

module top_module (    input clk,    input d,    output q);    reg q_p,q_n;    always@(posedge clk)        q_p <= d;    always@(negedge clk)        q_n <= d;    assign q = clk?q_p:q_n;endmodule

标准答案:

module top_module(    input clk,    input d,    output q);        reg p, n;        // A positive-edge triggered flip-flop    always @(posedge clk)        p <= d ^ n;            // A negative-edge triggered flip-flop    always @(negedge clk)        n <= d ^ p;        // Why does this work?     // After posedge clk, p changes to d^n. Thus q = (p^n) = (d^n^n) = d.    // After negedge clk, n changes to d^p. Thus q = (p^n) = (p^d^p) = d.    // At each (positive or negative) clock edge, p and n FFs alternately    // load a value that will cancel out the other and cause the new value of d to remain.    assign q = p ^ n;            // Can't synthesize this.    /*always @(posedge clk, negedge clk) begin        q <= d;    end*/        endmodule