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

📄 cia8520.v

📁 Verilog, c and asm source codes of the Minimig system, a fpga implementation of the Amiga computer.
💻 V
📖 第 1 页 / 共 2 页
字号:
);//----------------------------------------------------------------------------------//instantiate timer A//----------------------------------------------------------------------------------timera tmra(	.clk(clk),	.wr(wr),	.reset(reset),	.tlo(talo),	.thi(tahi),	.tcr(cra),	.datain(datain),	.dataout(tmraout),	.eclk(e),	.tmra_ovf(tmra_ovf),	.irq(ta) );//----------------------------------------------------------------------------------//instantiate timer B//----------------------------------------------------------------------------------timerb tmrb(	.clk(clk),	.wr(wr),	.reset(reset),	.tlo(tblo),	.thi(tbhi),	.tcr(crb),	.datain(datain),	.dataout(tmrbout),	.eclk(e),	.tmra_ovf(tmra_ovf),	.irq(tb));//----------------------------------------------------------------------------------//instantiate timer D//----------------------------------------------------------------------------------timerd tmrd (	.clk(clk),	.wr(wr),	.reset(reset),	.tlo(tdlo),	.tme(tdme),	.thi(tdhi),	.tcr(crb),	.datain(datain),	.dataout(tmrdout),	.count(tick),	.irq(alrm)); endmodule//----------------------------------------------------------------------------------//----------------------------------------------------------------------------------//interrupt control//----------------------------------------------------------------------------------//----------------------------------------------------------------------------------module ciaint(	input 	clk,	  			//clock	input	wr,					//write enable	input 	reset, 				//reset	input 	icrs,				//intterupt control register select	input	ta,					//ta (set TA bit in ICR register)	input	tb,				    //tb (set TB bit in ICR register)	input	alrm,	 			//alrm (set ALRM bit ICR register)	input 	flag, 				//flag (set FLG bit in ICR register)	input 	ser,				//ser (set SP bit in ICR register)	input 	[7:0]datain,		//bus data in	output 	reg [7:0]dataout,	//bus data out	output	irq					//intterupt out);	reg		[4:0]icr;				//interrupt register	reg		[4:0]icrmask;			//interrupt mask register//reading of interrupt data register always @(wr or irq or icrs or icr)	if(icrs && !wr)		dataout[7:0] = {irq,2'b0,icr[4:0]};	else		dataout[7:0] = 0;//writing of interrupt mask registeralways @(posedge clk)	if(reset)		icrmask[4:0] <= 0;	else if(icrs && wr)	begin		if(datain[7])			icrmask[4:0] <= icrmask[4:0] | datain[4:0];		else			icrmask[4:0] <= icrmask[4:0] & (~datain[4:0]);	end//register new interrupts and/or changes by user readsalways @(posedge clk)	if(reset)//synchronous reset			icr[4:0] <= 0;	else	if (icrs && !wr)	begin//clear latched intterupts on read		icr[0] <= ta;				//timer a		icr[1] <= tb;				//timer b		icr[2] <= alrm;   		//timer tod		icr[3] <= ser;	 		//external ser input		icr[4] <= flag;			//external flag input	end	else	begin//keep latched intterupts		icr[0] <= icr[0]|ta;		//timer a		icr[1] <= icr[1]|tb;		//timer b		icr[2] <= icr[2]|alrm;	//timer tod		icr[3] <= icr[3]|ser;	//external ser input		icr[4] <= icr[4]|flag;	//external flag input	end//generate irq output (interrupt request)assign irq 	= (icrmask[0]&icr[0]) 			| (icrmask[1]&icr[1])			| (icrmask[2]&icr[2])			| (icrmask[3]&icr[3])			| (icrmask[4]&icr[4]);endmodule//----------------------------------------------------------------------------------//timer A/B//----------------------------------------------------------------------------------module timera(	input 	clk,	  				//clock	input	wr,						//write enable	input 	reset, 					//reset	input 	tlo,					//timer low byte select	input	thi,		 			//timer high byte select	input	tcr,					//timer control register	input 	[7:0]datain,			//bus data in	output 	[7:0]dataout,			//bus data out	input	eclk,	  				//count enable	output	tmra_ovf,				//timer A underflow	output	spmode,					//serial port mode	output	start,					//timer start (enable)	output	irq						//intterupt out);	reg		[15:0]tmr;			//timer 	reg		[7:0]tmlh;			//timer latch high byte	reg		[7:0]tmll;			//timer latch low byte	reg		[6:0]tmcr;			//timer control register	reg		forceload;				//force load strobe	wire	oneshot;				//oneshot mode	//wire	start;					//timer start (enable)	reg		oneshot_load;    		//load tmr after writing thi in one-shot mode	wire	reload;					//reload timer counter	wire	zero;					//timer counter is zero	wire	underflow;				//timer is going to underflow	wire	count;					//count enable signal	//count enable signal	assign count = eclk;	//writing timer control registeralways @(posedge clk)	if(reset)	//synchronous reset		tmcr[6:0] <= 0;	else if (tcr && wr)	//load control register, bit 4(strobe) is always 0		tmcr[6:0] <= {datain[6:5],1'b0,datain[3:0]};	else if (oneshot_load)	//start timer if thi is written in one-shot mode		tmcr[0] <= 1;	else if (underflow && oneshot) //stop timer in one-shot mode		tmcr[0] <= 0;always @(posedge clk)	forceload <= tcr & wr & datain[4];	//force load strobe 	assign oneshot = tmcr[3];		//oneshot aliasassign start = tmcr[0];		//start aliasassign spmode = tmcr[6];		//serial port mode (0-input, 1-output)//timer A latches for high and low bytealways @(posedge clk)	if (reset)		tmll[7:0] <= 8'b11111111;	else if (tlo && wr)		tmll[7:0] <= datain[7:0];		always @(posedge clk)	if (reset)		tmlh[7:0] <= 8'b11111111;	else if (thi && wr)		tmlh[7:0] <= datain[7:0];//thi is written in one-shot mode so tmr must be reloadedalways @(posedge clk)	oneshot_load <= thi & wr & oneshot;//timer counter reload signalassign reload = oneshot_load | forceload | underflow;//timer counter	always @(posedge clk)	if (reset)		tmr[15:0] <= 0;	else if (reload)		tmr[15:0] <= {tmlh[7:0],tmll[7:0]};	else if (start && count)		tmr[15:0] <= tmr[15:0] - 1;//timer counter equals zero		assign zero = ~|tmr;		//timer counter is going to underflowassign underflow = zero & start & count;//Timer A underflow signal for Timer Bassign tmra_ovf = underflow;//timer underflow interrupt requestassign irq = underflow;//data outputassign dataout[7:0] = ({8{~wr&tlo}} & tmr[7:0]) 					  | ({8{~wr&thi}} & tmr[15:8])					  | ({8{~wr&tcr}} & {1'b0,tmcr[6:0]});						endmodulemodule timerb(	input 	clk,	  				//clock	input	wr,						//write enable	input 	reset, 					//reset	input 	tlo,					//timer low byte select	input	thi,		 			//timer high byte select	input	tcr,					//timer control register	input 	[7:0]datain,			//bus data in	output 	[7:0]dataout,			//bus data out	input	eclk,	  				//count enable	input	tmra_ovf,			//timer A underflow	output	irq						//intterupt out);	reg		[15:0]tmr;			//timer 	reg		[7:0]tmlh;			//timer latch high byte	reg		[7:0]tmll;			//timer latch low byte	reg		[6:0]tmcr;			//timer control register	reg		forceload;				//force load strobe	wire	oneshot;				//oneshot mode	wire	start;					//timer start (enable)	reg		oneshot_load; 			//load tmr after writing thi in one-shot mode	wire	reload;					//reload timer counter	wire	zero;					//timer counter is zero	wire	underflow;				//timer is going to underflow	wire	count;					//count enable signal//Timer B count signal sourceassign count = tmcr[6] ? tmra_ovf : eclk;//writing timer control registeralways @(posedge clk)	if(reset)	//synchronous reset		tmcr[6:0] <= 0;	else if (tcr && wr)	//load control register, bit 4(strobe) is always 0		tmcr[6:0] <= {datain[6:5],1'b0,datain[3:0]};	else if (oneshot_load)	//start timer if thi is written in one-shot mode		tmcr[0] <= 1;	else if (underflow && oneshot) //stop timer in one-shot mode		tmcr[0] <= 0;always @(posedge clk)	forceload <= tcr & wr & datain[4];	//force load strobe 	assign oneshot = tmcr[3];					//oneshot aliasassign start = tmcr[0];					//start alias//timer B latches for high and low bytealways @(posedge clk)	if (reset)		tmll[7:0] <= 8'b11111111;	else if (tlo && wr)		tmll[7:0] <= datain[7:0];		always @(posedge clk)	if (reset)		tmlh[7:0] <= 8'b11111111;	else if (thi && wr)		tmlh[7:0] <= datain[7:0];//thi is written in one-shot mode so tmr must be reloadedalways @(posedge clk)	oneshot_load <= thi & wr & oneshot;//timer counter reload signalassign reload = oneshot_load | forceload | underflow;//timer counter	always @(posedge clk)	if (reset)		tmr[15:0] <= 0;	else if (reload)		tmr[15:0] <= {tmlh[7:0],tmll[7:0]};	else if (start && count)		tmr[15:0] <= tmr[15:0] - 1;//timer counter equals zero		assign zero = ~|tmr;		//timer counter is going to underflowassign underflow = zero & start & count;//timer underflow interrupt requestassign irq = underflow;//data outputassign dataout[7:0] = ({8{~wr&tlo}} & tmr[7:0]) 				| ({8{~wr&thi}} & tmr[15:8])				| ({8{~wr&tcr}} & {1'b0,tmcr[6:0]});						endmodule//----------------------------------------------------------------------------------//----------------------------------------------------------------------------------//timer D//----------------------------------------------------------------------------------//----------------------------------------------------------------------------------module timerd(	input 	clk,	  				//clock	input	wr,						//write enable	input 	reset, 					//reset	input 	tlo,					//timer low byte select	input 	tme,					//timer mid byte select	input	thi,		 			//timer high byte select	input	tcr,					//timer control register	input 	[7:0]datain,			//bus data in	output 	reg [7:0]dataout,		//bus data out	input	count,	  				//count enable	output	reg irq					//intterupt out);	reg		le;						//timer d output latch enable	reg 	ce;						//timer d count enable	reg		crb7;					//bit 7 of control register B	reg		[23:0]tod;			//timer d	reg		[23:0]alarm;			//alarm	reg		[15:0]todl;			//timer d latch//timer D output latch controlalways @(posedge clk)	if(reset)		le <= 1;	else if(!wr)	begin		if(thi)//if MSB read, hold data for subsequent reads			le <= 0;		else if (tlo)//if LSB read, update data every clock			le <= 1;	endalways @(posedge clk)	if(le)		todl[15:0] <= tod[15:0];//timer D and crb7 read always @(wr or tlo or tme or thi or tcr or tod or todl or crb7)	if (!wr)	begin		if(thi)//high byte of timer D			dataout[7:0] = tod[23:16];		else if (tme)//medium byte of timer D (latched)			dataout[7:0] = todl[15:8];		else if (tlo)//low byte of timer D (latched)			dataout[7:0] = todl[7:0];		else if (tcr)//bit 7 of crb			dataout[7:0] = {crb7,7'b0000000};		else			dataout[7:0] = 0;	end	else		dataout[7:0] = 0;  //timer D count enable controlalways @(posedge clk)	if(reset)		ce <= 1;	else if(wr && !crb7)//crb7==0 enables writing to TOD counter	begin		if(thi || tme)//stop counting			ce <= 0;		else if(tlo)//write to LSB starts counting again			ce <= 1;				end//timer D counteralways @(posedge clk)	if(reset)//synchronous reset	begin		tod[7:0] <= 0;		tod[15:8] <= 0;		tod[23:16] <= 0;	end	else if(wr && !crb7)//crb7==0 enables writing to TOD counter	begin		if(tlo)			tod[7:0] <= datain[7:0];		if(tme)			tod[15:8] <= datain[7:0];		if(thi)			tod[23:16] <= datain[7:0];	end	else if(ce && count)		tod[23:0] <= tod[23:0]+1;//alarm writealways @(posedge clk)	if(reset)//synchronous (p)reset	begin		alarm[7:0] <= 8'b11111111;		alarm[15:8] <= 8'b11111111;		alarm[23:16] <= 8'b11111111;	end	else if(wr && crb7)//crb7==1 enables writing to ALARM	begin		if(tlo)			alarm[7:0] <= datain[7:0];		if(tme)			alarm[15:8] <= datain[7:0];		if(thi)			alarm[23:16] <= datain[7:0];	end//crb7 writealways @(posedge clk)	if (reset)		crb7 <= 0;	else if(wr && tcr)		crb7 <= datain[7];//alarm interruptalways @(tod or alarm or count)	if( (tod[23:0]==alarm[23:0]) && count)		irq = 1;	else 		irq = 0;endmodule

⌨️ 快捷键说明

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