【牛客】3 时序逻辑
VL21 根据状态转移表实现时序电路
写一个简单的Moore状态机就可以了,太短就懒得写三段式了。
`timescale 1ns/1ns module seq_circuit( input A , input clk , input rst_n, output wire Y ); reg [1:0]state; always@(posedge clk or negedge rst_n) begin if(~rst_n) state <= 0; else begin case(state) 0:state <= A?3:1; 1:state <= A?0:2; 2:state <= A?1:3; 3:state <= A?2:0; endcase end end assign Y = (state == 2'b11); endmodule
VL22 根据状态转移图实现时序电路
因为输出定义的是wire变量,这里就直接用的assign输出了。
`timescale 1ns/1ns module seq_circuit( input C , input clk , input rst_n, output wire Y ); reg [1:0]state; reg [1:0]next_state; always@(posedge clk or negedge rst_n) begin if(~rst_n) state <= 0; else state <= next_state; end always@(*) begin case(state) 0:next_state = C?1:0; 1:next_state = C?1:3; 2:next_state = C?2:0; 3:next_state = C?2:3; endcase end assign Y = (state == 3)||(state == 2&&C); endmodule
VL23 ROM的简单实现
初始化想用initial的,但是initial不可综合。因为接口定义的是wire,所以直接用assign输出。
ram的话就在always块内赋值即可。
`timescale 1ns/1ns module rom( input clk, input rst_n, input [7:0]addr, output [3:0]data ); reg [3:0]rom[0:7]; always@(posedge clk or negedge rst_n) begin if(~rst_n)begin rom[0] <= 0; rom[1] <= 2; rom[2] <= 4; rom[3] <= 6; rom[4] <= 8; rom[5] <= 10; rom[6] <= 12; rom[7] <= 14; end end assign data = rom[addr]; endmodule
VL24 边沿检测
这题比较简单,把输入打一拍再进行比较,注意时序输出即可。
`timescale 1ns/1ns module edge_detect( input clk, input rst_n, input a, output reg rise, output reg down ); reg a_reg; always@(posedge clk or negedge rst_n)begin if(~rst_n)begin rise <= 1'b0; down <= 1'b0; a_reg <= 1'b0; end else begin a_reg <= a; if(a&&~a_reg) rise <= 1'b1; else rise <= 1'b0; if(~a&&a_reg) down <= 1'b1; else down <= 1'b0; end end endmodule
基础题还是比较简单的,明天开始进阶。