题解 | #根据状态转移图实现时序电路#
根据状态转移图实现时序电路
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