数字IC面试手撕代码(三)

输入in,输出out,对输入in维持的周期进行计数N;如果N<4,则out为0,如果N>4,则将out拉高,并保持N/4个周期数。
使用状态机:
c_state == 0 : IDLE
c_state 1 : 计数
c_state
2:计算out高电平持续时间
c_state==3:拉高out

对于这个题目我有点疑惑的就是in的维持时间会不会累加(就是持续一段时间高,又一会低,再继续高),还有个疑惑是N/4这应该是取整吧。如果不是取整,我觉得就有点难了,涉及到分数了。

module c_j (
	input clk,
	input rst_n,
	input in,
	output reg out
);
reg [1:0] c_state;
reg [1:0] n_state;

parameter IDLE = 2'b00;
parameter CACULATE = 2'b01;
parameter HOLD = 2'b10;
parameter UP = 2'b11;

reg [7:0] cnt;
reg [7:0] cnt_sub;
reg in_1;
reg in_2;
wire pose_in;

always @ (posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		in_1 <= 1'b0;
		in_2 <= 1'b0;
	end
	else begin
		in_1 <= in;
		in_2 <= in_1;
	end
end
assign pose_in = in_1 & (~in_2);
assign neg_in  = ~(in_1) & in_2;
always @ (posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		c_state <= IDLE;
	end
	else begin
		c_state <= n_state;
	end
end



always @ (*) begin
	case(c_state)
		IDLE : if(pose_in) 
					n_state <= CACULATE;
				else 
					n_state <= IDLE;
		CACULATE : if(neg_in)
						n_state <= HOLD;
					else 
						n_state <= CACULATE;
		HOLD : if(cnt > 4) n_state <= UP;
				else n_state <= IDLE;
		UP : if(cnt_sub=='d0) n_state <= IDLE;
			else n_state <= UP;
	endcase
end


always @ (posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		cnt <= 'd0;
	end
	else if(n_state==CACULATE) begin
		cnt <= cnt + 1'b1;
	end
	else if(n_state==IDLE) begin
		cnt <= 'd0;
	end

end

always @ (posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		cnt_sub <= 'd0;
	end
	else if(n_state==HOLD) begin
		cnt_sub <= cnt >> 2;
	end if(n_state==UP) begin
		cnt_sub <= cnt_sub - 1'b1;
	end
	// else begin
		// cnt_sub <='d0;
	// end
end

always @ (posedge clk or negedge rst_n) begin
	if(!rst_n) begin
		out <= 1'b0;
	end
	else if(n_state==UP) begin
		out <= 1'b1;
	end
	else begin
		out <= 1'b0;
	end
end

endmodule


测试代码:

`timescale 1ps/1ps
module tb();
reg in;
reg clk;
reg rst_n;
wire out;


c_j u1(
	.clk(clk),
	.in(in),
	.rst_n(rst_n),
	.out(out)
);

initial begin
	rst_n = 0;
	#15;
	rst_n = 1;
end

initial begin
	clk = 0;
	in= 0;
	#20;
	in = 1;
	#100;
	in = 0;
end

always #5 clk = ~clk;
endmodule

数字IC面试手撕代码(三)_第1张图片
这个代码就写的比较蠢了,但是功能实现了,还要啥自行车。

你可能感兴趣的:(数字IC,面试,撕代码)