题解 | #根据状态转移图实现时序电路#

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

https://www.nowcoder.com/practice/e405fe8975e844c3ab843d72f168f9f4

`timescale 1ns/1ns

module seq_circuit(
   input                C   ,
   input                clk ,
   input                rst_n,
 
   output   wire        Y   // Y 是 wire 型变量,不受时钟信号的约束改变
);


   //===========================================//
   // 逻辑表达式解法
   //===========================================//

   /*根据状态机的描述,从原始的状态函数定义出发,分别求出两位nxt_st和一位输出的表达式*/
   // 定位两位状态
   // reg [1:0] state
   reg st1, st0;
   always @(posedge clk or negedge rst_n) 
   begin
      if(~rst_n) begin
         st1 <= 1'b0;
         st0 <= 1'b0;
      end
      else begin
         st1 <= (st0&(~C))|(st1&C);
         st0 <= (st0&(~C))|(~st1&C);
      end
   end   

   assign Y = (st1&st0)|(st1&(~st0)&C);

   //===========================================//
   // 状态机解法
   //===========================================//

   // localparam
   // s0 = 3'b000,
   // s1 = 3'b001,
   // s2 = 3'b010,
   // s3 = 3'b100;

   // reg [2:0] cur_st, nxt_st;

   /*======三段式FSM 最后一段描述输出逻辑======*/
   /*
   always @(posedge clk or negedge rst_n) 
   begin
      if(~rst_n)
         cur_st <= s0;
      else
         cur_st <= nxt_st;
   end

   always @( *) begin
      case(cur_st)
         s0: nxt_st = C? s1 : s0;
         s1: nxt_st = C? s1 : s2;
         s2: nxt_st = C? s3 : s2;
         s3: nxt_st = C? s3 : s0;
         default :
            nxt_st = s0;
      endcase
   end

   // Y在定义中为wire信号,其值的改变不应当受限于时钟的上升沿、
   // 根据本体的报错,也是如此
   // 故,这里的第三段状态机使用组合逻辑
   reg y_r;
   assign Y = y_r;
   always @( *) begin
      if(~rst_n)
         y_r = 1'b0;
      else if(cur_st==s2 || (cur_st==s3 && C==1'b1))
         y_r = 1'b1;
      else
         y_r = 1'b0;
   end
   */

   /*======两段FSM 含输出======*/
   /*
   always @(posedge clk or negedge rst_n) 
   begin
      if(~rst_n)
         cur_st <= s0;
      else
         cur_st <= nxt_st;
   end

   reg y_r;
   assign Y = y_r;
   always @( *) begin
      case (cur_st)

         s0: begin
            nxt_st = C? s1 : s0;
            y_r = 1'b0;
         end

         s1: begin
            nxt_st = C? s1 : s2;
            y_r = 1'b0;
         end

         s2: begin
            nxt_st = C? s3 : s2;
            y_r = 1'b1;
         end

         s3: begin
            nxt_st = C? s3 : s0;
            y_r = C? 1'b1 : 1'b0;
         end

         default : begin
            nxt_st = s0;
            y_r = 1'b0;
         end
      endcase
   end
   */

   /*======两段FSM 不含输出======*/
   /*
   always @(posedge clk or negedge rst_n) 
   begin
      if(~rst_n)
         cur_st <= s0;
      else
         cur_st <= nxt_st;
   end

   always @( *) begin
      case(cur_st)
         s0: nxt_st = C? s1 : s0;
         s1: nxt_st = C? s1 : s2;
         s2: nxt_st = C? s3 : s2;
         s3: nxt_st = C? s3 : s0;
         default :
            nxt_st = s0;
      endcase
   end

   assign Y = (cur_st==s2) | (cur_st==s3 && C==1'b1);
   */

endmodule

全部评论

相关推荐

02-19 19:57
门头沟学院 Java
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务