天天看點

一天一道Verilog程式設計題(-)

編寫Verilog代碼:

輸入in,輸出為out,對輸入in維持的周期進行計數計數周期為N,如果N<4輸出out為0;如果N>4,則拉高out并保持N/4個周期數,限定out的輸出高電平數不大于6.

此題可以由狀态加上兩個計數器組成,狀态機有4個狀态分别為:

S_IDLE:初始狀态,

S_CNT:輸入信号高電平持續周期計數;

S_DE:判斷輸出高電平持續的周期數;

S_OUT:輸出out。

代碼,testbench以及仿真結果如下:

module count_in( out,in,clk,rst_n);
	parameter S0=2'b00,
			  S1=2'b01,
			  S2=2'b10,
			  S3=2'b11;
			  
	input in,clk,rst_n;
	output out;
	reg out;
	reg [2:0] current_state,next_state;
	
	reg [4:0] N;
	reg [2:0] width;
	
	
	
	always@(posedge clk or negedge rst_n)	
	begin
		if (!rst_n)
			current_state<=S0;
		else 
			current_state<=next_state;
	end
	
	always@(*)
	begin
		next_state=2'bxx;
		case(current_state)
			S0:begin
				if (in==1'b1)
					next_state=S1;
				else 
					next_state=S0;
			   end
			S1:begin
				if (in==1'b1)
					next_state=S1;
				else
					next_state=S2;
			   end
			S2:begin
					if (width==0)
						next_state=S0;
					else 
						next_state=S3;
				end
			S3:begin
					if (width==0)
						next_state=S0;
					else
						next_state=S3;
				end
			default:next_state=S0;
		endcase
	end
	
	always @ (*)
	begin
		if (current_state==S3)
			out=1'b1;
		else 
			out=1'b0;
	end
	always @ (posedge clk or negedge rst_n)
	begin
		if (!rst_n)
			N<=0;
		else if (current_state==S1)
		begin
			if (N<=5'd24)
				N<=N+1'b1;
			else 
				N<=N;
		end
		else if (current_state==S0)
			N<=0;
	end
	
	always @ (posedge clk or negedge rst_n)
	begin
		if (!rst_n)
			width<=0;
		else if (current_state==S1)
		begin
		if (N<4)
			width<=0;
		else if (N<8)
			width<=3'b001;
		else if (N<12)
			width<=3'b010;
		else if (N<16)
			width<=3'b011;
		else if (N<20)
			width<=3'b100;
		else if (N<24)
			width<=3'b101;
		else 
			width<=3'b110;
		end
		else if (current_state==S3)
			width<=width-1'b1;
	end
endmodule 
			
           
module count_in_t;
	reg clk,rst_n;
	reg in;
	wire out;
	
	count_in U1(.clk(clk),.rst_n(rst_n),.in(in),.out(out));
	
	initial 
	begin
		clk=1'b0;
		forever #10 clk=~clk;
	end
	
	initial
	begin
		rst_n=1'b1;
		in=1'b0;
		#10 rst_n=1'b0;
		#10 rst_n=1'b1; in=1'b1;
		#600 in=1'b0;
	end
endmodule 
           
一天一道Verilog程式設計題(-)

繼續閱讀