Skip to content

数字系统设计实验

约 709 个字 2 张图片 预计阅读时间 2 分钟

Summary

实验课一共提交两次实验报告。lab5我相对写的比较潦草,lab12是大作业,写的还是相对认真的,可惜最后总评分不高,应该是我用了三段式而不是二段式的缘故吧。

实验考允许带开卷考资料,下面是我打印的东西。

lab5

lab12

实验考复习

除下面内容外,还打印了软件的基本使用方法(课本).

状态机

module controller(
    input in,
    input clk,
    input reset,
    output reg count,
    output reg clr,
    output reg first
);
    //三段式
    //状态编码
    parameter RESET = 2'b00;
    parameter TIMING = 2'b01;
    parameter FIRST = 2'b10;
    parameter STOP = 2'b11;

    ///machine variable
    reg [1:0] st_next;//next state
    reg [1:0] st_cur;//current state

    //1. state transfer
    always @(posedge clk or posedge reset)begin
        if(reset)
            st_cur=RESET;
        else
            st_cur=st_next;
    end

    //2.state switch
    always @(*)begin
        case(st_cur)
            RESET:
                case(in)
                    1'b0: st_next=RESET;
                    1'b1: st_next=TIMING;
                endcase
            TIMING:
                case(in)
                    1'b0: st_next=TIMING;
                    1'b1: st_next=FIRST;
                endcase
            FIRST:
                case(in)
                    1'b0: st_next=FIRST;
                    1'b1: st_next=STOP;
                endcase
            STOP:
                case(in)
                    1'b1: st_next=RESET;
                    1'b0: st_next=STOP;
                endcase
        endcase
    end
    //3. output logic
    always @(posedge clk or posedge reset) begi
        //如果没开始,就不用计时,输出也是0
        else begin
            case(st_cur)
                RESET: begin
                    clr <= 1;
                    count <= 0;
                    first <=0;
                end
                TIMING: begin
                    clr <= 0;
                    count <= 1;
                    first <=0;
                end
                FIRST: begin
                    clr <= 0;
                    count <= 1;
                    first <=1;
                end
                STOP: begin
                    clr <= 0;
                    count <= 0;
                    first <=0;
                end
            endcase
        end
    end
endmodule

触发器

module dffre(d, en, r, clk, q);
parameter n = 1;
output [n-1:0]  q;
input d, en, r, clk;
reg[n-1:0] q;

always@(posedge clk)
begin
    if(r == 1'b1)begin
        q <= 0;
    end
    else begin
        if(en == 1'b1)begin
            q <= d;
        end
        else begin
            q <= q;
        end
    end
end
endmodule

计数器

module counter_n(clk,en,r,q,co);
  parameter  n=4; 
  parameter  counter_bits=2;
  input   clk,en,r ;
  output  co;
  output [counter_bits-1:0]  q;
  reg [counter_bits-1:0]  q=0;
  assign  co=(q==(n-1)) && en;
  always @(posedge clk) 
  begin
      if(r) q=0;
        else if(en)  
              begin  
                if(q==(n-1))  q=0 ;
                else q=q+1;      
            end
  end
endmodule

计时器

module count_time #(
    parameter n = 10,              // 计时器的最大计数值
    parameter counter_bits = 4     // 计数器所需的位数
) (
    input clk,                     // 时钟信号
    input r,                       // 复位信号
    input en,                      // 使能信号
    output done                    // 计时完成信号
);
    reg [counter_bits-1:0] q;      // 计数器寄存器
    assign done = (q == n-1);      // 当计数器达到最大值时,done 信号置高

    always @(posedge clk) begin
        if (r) begin
            q <= 0;                // 复位信号有效时,将计数器清零
        end else if (en) begin
            q <= q + 1;            // 使能信号有效时,计数器递增
        end else begin
            q <= q;                // 其他情况下,保持计数器值不变
        end
    end
endmodule

Testbench

module controller_tb;
parameter dely = 10;
reg in;
reg clk;
reg reset;
wire clr;
wire count;
//实例化

controller u_controller(
    .clk(clk),
    .in(in),
    .reset(reset),
    .count(count),
    .clr(clr)
);

initial begin
    clk = 0;
    forever #(dely) clk  = ~clk;
end

initial begin
    //初始化
    in=0;
    reset = 1;
    #(5*dely);
    reset=0;
    #(5*dely);
    in=0;
    #(5*dely);
    in=1;
    #(5*dely);
    in=0;
    #(5*dely);
    in=1;
    #(5*dely);
    in=0;
    #(5*dely);
    in=1;
    #(5*dely);
    $finish;
end

initial begin
    $monitor("Time = %0t, clk = %b, reset = %b, in = %b, clr = %b, count = %b", $time, clk, reset, in, clr, count);
end

endmodule

也有这种写法:

    //  clr
    initial 
     begin
       clk = 0;r=0;en = 0;
       #(51) r=1;
       #(100)r=0 ;
       repeat (620)  begin 
         #(100*3)  en=1;
         # 100  en=0; end
         #1000 $stop;
  end

一些框图:

同步器:

|400

防颤电路:

|375

Comments