⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usiecntr.v

📁 USBRTL电路的VHDL和Verilog代码
💻 V
字号:
/******************************************
	Filename: 	siecntr.v 1.14
******************************************/

/*
The sie counter module counts active and inactive and se0.  If inactive
it first detects turnaround 17 clocks, and signals to the device that a
response, if expected, isn't coming.  If it is inactive for a LONG time
it turns on suspend.  If it sees se0 for MAXSE0 (33 clocks) it signals
reset
*/
module Usiecntr
	(
	// inputs
		usbclock,
		syncreset,
		syncidle,
		syncse0,
		xmitactive,
		vpin,
		resumen,
                testmode,
                testreset,

	// outputs
		turnaround,
		se0reset,
		suspend,
		oktoxmit
	);

`include "Usiecntrdef.v"

input	usbclock;
input	syncreset;	// synopsys sync_set_reset "syncreset"
input	syncidle;
input	syncse0;
input	xmitactive;
input	vpin;
input	resumen;
input   testmode;
input   testreset;

output	suspend;
output	turnaround;
output	se0reset;
output	oktoxmit;

reg	[15:0] cyclecount;
reg	resetsuspend;
reg	oktoxmit;
reg	resetturnaround;
reg	turnaround;
reg	resetse0reset;
reg	se0reset;

reg	[2:0]	cntrst, nextcntrst;

wire	stayinsuspend = ((cntrst == CNTRSLEEP) && vpin && resumen);
wire    rstn ;
// special aysnc flop logic for usbclockout 
assign  rstn = (testmode)? testreset : (~(syncreset || ~vpin || ~resumen));
dffr asyncflop (
	.q (suspend),
	.d (stayinsuspend),
	.clk (usbclock),
	.rstn (rstn)	// either reset high or resumen or vpin low keeps us out of suspend
	);

always @(posedge usbclock)
begin
	if (resetturnaround)
		turnaround <= 1'b0;
	else if ((cntrst == CNTRINACTIVE) && (cyclecount == MAXTURNAROUND))
		turnaround <= 1'b1;

	if (resetturnaround) 
		oktoxmit <= 1'b0;
	// used to be I'd wait two clocks, but since our internal flops put us
	// a clock behind the bus, lets say ok right away
	//else if ((cntrst == CNTRINACTIVE) && (cyclecount != 1'b0))	// 2 clocks - 1 here, plus 1 till it goes active
	else if (nextcntrst == CNTRINACTIVE)	// if we see it going inactive, its ok to send
		oktoxmit <= 1'b1;
	else
		oktoxmit <= 1'b0;

	if (resetse0reset)
		se0reset <= 1'b0;
	else if (se0reset && (cntrst == CNTRSE0))	// once triggered, keep it until SE0 goes away
		se0reset <= 1'b1;
	else if ((cntrst == CNTRSE0) && (cyclecount == MAXSE0))
		se0reset <= 1'b1;
end

always @(posedge usbclock)
begin
	if (resetsuspend && resetturnaround && resetse0reset)
		cyclecount <= 1'b0;
	else
		cyclecount <= cyclecount + 1'b1;
end

// state machine for counting weird cycles
always @(posedge usbclock)
begin
	cntrst <= nextcntrst;
end

always @(cntrst or syncreset or cyclecount or syncidle or syncse0 or xmitactive or vpin or resumen)
begin
	if (syncreset)
	begin
		nextcntrst = CNTRIDLE;
		resetturnaround = 1'b1;
		resetsuspend = 1'b1;
		resetse0reset = 1'b1;
	end
	else
		case (cntrst)	// synopsys parallel_case full_case
			CNTRIDLE:
			begin
				resetturnaround = 1'b1;
				resetsuspend = 1'b1;
				resetse0reset = 1'b1;
				if (xmitactive)
					nextcntrst = CNTRACTIVE;	
				else if (syncse0)
					nextcntrst = CNTRSE0;
				else if (syncidle)
					nextcntrst = CNTRINACTIVE;
				else
					nextcntrst = CNTRIDLE;
			end
			CNTRINACTIVE:
			begin
				resetse0reset = 1'b1;
				if (cyclecount == MAXINACTIVE)
				begin
					resetturnaround = 1'b0;
					resetsuspend = 1'b0;
					nextcntrst = CNTRSLEEP;
				end
				else if (xmitactive)
				begin
					resetturnaround = 1'b0;
					resetsuspend = 1'b0;
					nextcntrst = CNTRACTIVE;	
				end
				else if (syncse0)
				begin
					resetturnaround = 1'b1;
					resetsuspend = 1'b1;
					nextcntrst = CNTRSE0;
				end
				else if (syncidle)
				begin
					resetturnaround = 1'b0;
					resetsuspend = 1'b0;
					nextcntrst = CNTRINACTIVE;
				end
				else 
				begin
					resetturnaround = 1'b1;
					resetsuspend = 1'b1;
					nextcntrst = CNTRACTIVE;	
				end
			end
			CNTRACTIVE:
			begin
				resetturnaround = 1'b1;
				resetsuspend = 1'b1;
				resetse0reset = 1'b1;
				if (xmitactive)
					nextcntrst = CNTRACTIVE;	
				else if (syncse0)
					nextcntrst = CNTRSE0;
				else if (syncidle)
					nextcntrst = CNTRINACTIVE;
				else 
					nextcntrst = CNTRACTIVE;	
			end
			CNTRSE0:
			begin
				resetturnaround = 1'b1;
				resetsuspend = 1'b1;
				// can't really be here and have xmitactive
				if (syncse0)
				begin
					nextcntrst = CNTRSE0;
					resetse0reset = 1'b0;
				end
				else if (syncidle)
				begin
					nextcntrst = CNTRINACTIVE;
					resetse0reset = 1'b1;
				end
				else 
				begin
					nextcntrst = CNTRACTIVE;	
					resetse0reset = 1'b1;
				end
			end
			CNTRSLEEP:
			begin
				resetturnaround = 1'b1;
				resetsuspend = 1'b1;
				resetse0reset = 1'b1;
				// can't really be here and have xmitactive
				if (~vpin || ~resumen)
					nextcntrst = CNTRACTIVE;	
				else 
					nextcntrst = CNTRSLEEP;
			end
	endcase
end

// make the ascii version of the cntr state
// synopsys translate_off
reg [8*15:1]	cntrstate;
always @(cntrst)
case (cntrst)
	CNTRIDLE : cntrstate = "CNTRIDLE";
	CNTRACTIVE : cntrstate = "CNTRACTIVE";
	CNTRINACTIVE : cntrstate = "CNTRINACTIVE";
	CNTRTURNAROUND : cntrstate = "CNTRTURNAROUND";
	CNTRSLEEP : cntrstate = "CNTRSLEEP";
	CNTRSE0 : cntrstate = "CNTRSE0";
endcase
// synopsys translate_on

endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -