牛客Verilog题目(2)——根据状态转移表实现时序电路

前20题大都是组合逻辑电路,时序电路最大的不同就是要用到触发器,程序中一般还是边沿触发,就以第21题为例

第二题来自牛客->verilog快速入门->第21题

1.题目

在这里插入图片描述

2.模块函数

代码还是比较简单的,这里只需要注意要用非阻塞赋值即可。

module test2(
        input                A   ,
        input                clk ,
        input                rst_n,
        output   wire        Y,
        output   reg        Q1, 
        output   reg        Q2  
    );
    always@(posedge clk,negedge rst_n) begin
        if(rst_n) begin
            Q1 <= ~Q1;
            Q2 <= Q2^Q1^A;
        end
        else begin
            Q1<=1'B0;
            Q2<=1'B0;
        end
    end
    assign Y = Q1&Q2;
endmodule

在这里插入图片描述
在这里插入图片描述

3.激励函数

激励文件(顶层文件)代码也需要非阻塞赋值(一开始就是这里搞错了):

module test_top();
reg A;
reg rst_n ;
reg clk = 1;
wire Y,Q1,Q2;
always   #5 clk = ~clk;
initial begin
    rst_n <= 1'b1;
    A <= 1'b1;
    #300 $finish;
    end

test2 seq(
    .A(A),
    .rst_n(rst_n),
    .clk(clk),
    .Y(Y),
    .Q1(Q1),
    .Q2(Q2)
    );
endmodule

4.仿真结果

经过RTL仿真得到上图,但是如果用综合仿真会得到下图情况:
在这里插入图片描述
在这里插入图片描述
但是行为仿真会得到正常情况:
在这里插入图片描述
这里又复习了最开始的学习:
在这里插入图片描述
分别是行为仿真、综合仿真、实现仿真,我的理解就是行为仿真相当于代码验证和功能验证,而综合仿真需要根据你事先选择的赛灵思芯片型号来给当前代码用到的逻辑器件配置相应的实际元器件,再进行仿真。实现仿真则是考虑到具体元器件之间的布局布线,会告诉你这些元器件都在哪些位置。

第二题来自牛客->verilog快速入门->第22题

1.题目

在这里插入图片描述

2.方法一:触发器

`timescale 1ns/1ns

module seq_circuit(
   input                C   ,
   input                clk ,
   input                rst_n,
 
   output   wire        Y   
);
reg Q1,Q0,T;
always@(posedge clk or negedge rst_n ) begin
    if(rst_n) begin
        Q1 <= Q1&C | Q0&~C;
    end
    else begin
        Q1 <= 1'B0;
    end
end

always@(posedge clk or negedge rst_n ) begin
    if(rst_n) begin
        Q0 <= ~Q1&C | Q0&~C;
    end
    else begin
        Q0 <= 1'B0;
    end
end

assign Y = Q1&Q0 | Q1&C;
endmodule

和上一题差不多

3.方法二:状态机

`timescale 1ns/1ns

module seq_circuit(
   input                C   ,
   input                clk ,
   input                rst_n,
 
   output   wire        Y   
);
    parameter ST0 = 2'b00;
    parameter ST1 = 2'b01;
    parameter ST2 = 2'b10;
    parameter ST3 = 2'b11;
    
    reg[1:0] cur_state;
    reg[1:0] next_state;
    reg Y_r;

    always@(posedge clk or negedge rst_n)
        if(!rst_n)
            cur_state <= ST0;
        else
            cur_state <= next_state;

    always@(*)
        case (cur_state)
            ST0: begin
                if(C == 1'b0) begin
                    next_state = ST0;
                end else begin
                    next_state = ST1;
                end
            end
            ST1: begin
                if(C == 1'b0) begin
                    next_state = ST3;
                end else begin
                    next_state = ST1;
                end
            end
            ST2: begin
                if(C == 1'b0) begin
                    next_state = ST0;
                end else begin
                    next_state = ST2;
                end
            end
            ST3: begin
                if(C == 1'b0) begin
                   next_state = ST3;
                end else begin
                    next_state = ST2;
                end
            end
        endcase

        always@(*)
        case (cur_state)
            ST0: begin
               Y_r = 1'b0;
            end
            ST1: begin
               Y_r = 1'b0;
            end
            ST2: begin
                if(C == 1'b1)
                    Y_r = 1'b1;
                else
                    Y_r = 1'b0;
            end
            ST3: begin
                Y_r = 1'b1;
            end
        endcase
    assign Y = Y_r;
endmodule

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值