Verilog刷题日志

参考博文:题解 | #根据状态转移表实现时序电路#_牛客博客 (nowcoder.net)

VL21 根据状态转移表实现时序电路

某同步时序电路转换表如下,请使用D触发器和必要的逻辑门实现此同步时序电路,用Verilog语言描述。其接口 input   A  ,input  clk , input  rst_n;output   wire Y 。

根据该转换表和题目,可以发现不同的A值,对于受 Q_{1}^{n}Q_{0}^{n}控制的Q_{1}^{n+1}Q_{0}^{n+1}、Y取值不同。但是 Q_{1}^{n}Q_{0}^{n}又不是输入信号,那么它是怎么变换的呢?我们发现表中存在Q_{1}^{n+1}Q_{0}^{n+1}信号,转换表蕴含了 Q_{1}^{n}Q_{0}^{n}的时钟变化规律。结合题目要采用D触发器实现,代表一个always块只能控制一个信号变量。因此列出Q_{1}^{n+1}Q_{0}^{n+1}的真值表。

由于逻辑表达式的化简结果不同,我们采用最小项表示(不需要进行化简,化简会出错):

q1 <= (~A & ~q1 & q0) | (~A & q1 & ~q0) | (A & ~q1 & ~q0) | (A & q1 & q0);

q0 <= (~A & ~q1 & ~q0) | (~A & q1 & ~q0) | (A & ~q1 & ~q0) | (A & q1 & ~q0);

上式的左侧q1、q0代表Q_{1}^{n+1}Q_{0}^{n+1},而右侧为Q_{1}^{n}Q_{0}^{n}

对于输出Y,其值只受当前的Q_{1}^{n}Q_{0}^{n}控制,真值表有:

  有逻辑表达式Y = q0 & q1;

采用D触发器实现,则有两个always块分别控制Q_{1}^{n}Q_{0}^{n}信号的变化,所有代码如下:

`timescale 1ns/1ns

module seq_circuit(
      input                A   ,
      input                clk ,
      input                rst_n,
  
      output   wire        Y  
);
    reg q0, q1;
     
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n) begin
            q1 <= 0;
        end
        else begin
           // q1 <= A ^ q0 ^ q1;
           q1 <= (~A & ~q1 & q0) | (~A & q1 & ~q0) | (A & ~q1 & ~q0) | (A & q1 & q0);
        end
    end
     
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n) begin
            q0 <= 0;
        end
        else begin
            //q0 <= ~q0;
            q0 <= (~A & ~q1 & ~q0) | (~A & q1 & ~q0) | (A & ~q1 & ~q0) | (A & q1 & ~q0);
        end
    end
    assign Y = q0 & q1;
endmodule

这里记录一下自己出现的问题,刚开始自己是采用状态机去实现状态转换,但是回归题目说使用D触发器就懵逼了,也看不懂题目是什么意思。看了其他博客的答案后自己写

Q_{1}^{n+1}Q_{0}^{n+1}逻辑表达式时,对其进行了化简,出现编译无法通过的情况,是由于自己卡诺图画错了。还有自己综合了使用状态机实现状态转换跟D触发器实现状态转换的资源占用率,区别非常大。下面为截图记录。

使用D触发器实现状态转移

正确状态机描述代码: 

`timescale 1ns/1ns

module seq_circuit(
      input                A   ,
      input                clk ,
      input                rst_n,
 
      output   wire        Y   
);
    
    reg [1:0] curr_state;
    reg [1:0] next_state;
    // one step
    always @ (posedge clk or negedge rst_n)
        begin
            if( ~rst_n ) begin
                curr_state <= 2'b00;
                next_state <= 2'b00;
            end 
            else begin
                curr_state <= next_state;
            end 
        end 
    
    // two step
    always @ (*)
        begin
            case(curr_state)
                2'b00 : next_state = (A == 1'b1) ? 2'b11 : 2'b01;
                2'b01 : next_state = (A == 1'b1) ? 2'b00 : 2'b10;
                2'b10 : next_state = (A == 1'b1) ? 2'b01 : 2'b11;
                2'b11 : next_state = (A == 1'b1) ? 2'b10 : 2'b00;
                default : next_state = 2'b00;
            endcase
        end
    
    assign Y = (curr_state == 2'b11) ? 1 : 0;
    
endmodule

状态机描述代码(没能够抓住Q1Q0的含义,Q1Q0表示current_state,Q_{1}^{n+1}Q_{0}^{n+1}表示next_state

,以为是随周期递增而已,自己的错误代码跟综合结果): 

使用状态机
`timescale 1ns/1ns

module seq_circuit(
      input                A   ,
      input                clk ,
      input                rst_n,
 
      output   wire        Y   
);

parameter S1A = 2'b01;
parameter S2A = 2'b10;
parameter S3A = 2'b11;
parameter S4A = 2'b00;

parameter S1B = 2'b11;
parameter S2B = 2'b00;
parameter S3B = 2'b01;
parameter S4B = 2'b10;

reg [1:0]current_state, next_state;
reg [1:0]Q;
reg y_temp;

assign Y = y_temp;

always@(posedge clk or negedge rst_n)begin
    if(rst_n == 1'b0)
        Q = 2'b00;
    else
        Q = Q + 1'b1;
end

always@(posedge clk or negedge rst_n)begin
    if(A == 1'b0)begin
        if(rst_n == 1'b0)
            current_state <= S1A;
        else
            current_state <= next_state;
    end
    else begin
        if(rst_n == 1'b0)
            current_state <= S1B;
        else
            current_state <= next_state;
    end
end

always@(*)begin
    if(A == 1'b0)begin
        if(rst_n == 1'b0)
            next_state <= S1A;
        else begin 
            case(current_state)
                S1A:begin    
                    if(Q == 2'b01)
                        next_state = S2A;
                    else
                        next_state = S1A;
                end
                S2A:begin
                    if(Q == 2'b10)
                        next_state = S3A;
                    else
                        next_state = S2A;
                end                    
                S3A:begin
                    if(Q == 2'b11)
                        next_state = S4A;
                    else
                        next_state = S3A;
                end
                S4A:begin
                    if(Q == 2'b00)
                        next_state = S1A;
                    else
                        next_state = S4A;
                end
                default:next_state = S1A;
            endcase
        end
    end
    else begin
         if(rst_n == 1'b0)
            next_state <= S1B;
        else begin 
            case(current_state)
                S1B:begin    
                    if(Q == 2'b01)
                        next_state = S2B;
                    else
                        next_state = S1B;
                end
                S2B:begin
                    if(Q == 2'b10)
                        next_state = S3B;
                    else
                        next_state = S2B;
                end                    
                S3B:begin
                    if(Q == 2'b11)
                        next_state = S4B;
                    else
                        next_state = S3B;
                end
                S4B:begin
                    if(Q == 2'b00)
                        next_state = S1B;
                    else
                        next_state = S4B;
                end
                default:next_state = S1B;
            endcase
        end       
    end
end

always@(posedge clk or negedge rst_n)begin
    if(A == 1'b0)begin
        if(rst_n == 1'b0)
            y_temp <= 1'b0;
        else begin
            case(next_state)
                S4A: y_temp <= 1'b1;
                default:y_temp <= 1'b0;
            endcase
        end
    end
    else begin
        if(rst_n == 1'b0)
            y_temp <= 1'b0;
        else begin
            case(next_state)
                S4B: y_temp <= 1'b1;
                default:y_temp <= 1'b0;
            endcase
        end
    end
end

endmodule

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值