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

📄 8251_8055_verilog.txt

📁 8251和8055的verilog源码
💻 TXT
📖 第 1 页 / 共 4 页
字号:
txd=0;                       //then send a start bit 1st   
repeat(baudmx) @(negedge txc_); 
end 
 
repeat(databits)   //send all start,databits 
begin 
txd=serial_data[0]; 
repeat(baudmx)  @(negedge txc_); 
serial_data=serial_data>>1; 
end 
 
if (modreg [4])              //  if parity is enabled ...
begin 
parity_bit=^(tdata_out & data_mask); 
if(modreg[5]==0) parity_bit= ~parity_bit;  // odd parity 
 
txd=parity_bit; 
repeat(baudmx)  @(negedge txc_);       //then send the parity bit 
end 
 
if(tstoptotal  != 0)       // if sync mode 
begin 
txd=1;       //then send out the stop bit (s 
repeat(tstoptotal)    @(negedge txc_); 
end  
 
tdata_out_full=0;  // block this routine until data/sync char to be sent 
                   // is immediately transferred to tdata_out. 
  
->txende;         //decide what data should be sent (data/sync/stop bit) 
end 
 
event transmit_held_data_e,transmitter_idle_e; 
 
always @txende 	      //end of transmitted data/sync character 
begin :trans2 
case (command[0] & ~cts_) 
0:	                   //if its is not now cts 
		               //but data was received while it was c 
if (tdata_hold_full && tdata_hold_cts) 
-> transmit_held_data_e;        // then send the data char 
else  
->transmitter_idle_e;   //else send sync char(s) or 1 stop bit 
 
1:		//if its is now cts 
if (tdata_hold_full) // if a character has been received  
//but now yet ransmitted ... 
->transmit_held_data_e; // then send the data char 
else 			// else (no character has been received 
-> transmitter_idle_e; 	//	send sync char(s) or 1 stop bit 
endcase 
end 
 
always @ (transmitter_idle_e) 	//if there are no data chars to send ...,
begin : trans3 
	status[2]=1;	                    // mard transmitter as being empty 
	txe=1; 
if (tstoptotal !=0 || command[0] ==0 ||cts_ ==1) 
      // if async mode or after areset or TxEnable = false or cts =false 
		begin 
			if (dflags[1]) 
				$display("I8251A (%h) at %d : transmitting data : 1 (stop bit)", 
                                                      instance_id ,$time); 
			txd=1;	      //then  send out 1 stop bit and make any writes  
tdata_out=1;			// go to tdata_hold 
			repeat(baudmx) @(negedge txc_); 
    			->txende; 
   		end 
else 				// if sync mode 
case (sync_to_transmit) 
1: 
		begin 
			tdata_out=sync1 >> (8-databits); 
			tdata_out_wait=0; 	// without waiting on negedge t 
			tdata_out_full=1; 
			if(modreg[7] == 0)	// if double sync mode 
				sync_to_transmit =2;// send 2nd sync after 1st 
		end 
2: 
		begin 
			tdata_out =sync2 >> (8-databits); 
			tdata_out_wait =0 ; 	// without waiting on negedge t 
			tdata_out_full =1 ; 
			sync_to_transmit = 1; 	//send 1st sync char next 
		end 
endcase 
end 
 
always @ (transmit_held_data_e) 	// if a character has been received *****add ()  
begin : trans4 
	tdata_out=tdata_hold;	 // but not transmitted ... 
	tdata_out_wait = 0;	     // then do not wait on negedge txc 
	tdata_out_full = 1;		 // and send the char immediately 
	tdata_hold_full = 0 ;   
	repeat (`TTXRDY ) @(posedge clk); 
	status[0] = 1;			 // and set the txrdy status bit 
end 
 
//************************* RECEIVER PORTION OF THE 8251A *******************/ 
// data is received at leading edge of the clock 
event break_detect_e,	
	  break_delay_e;		// 
event hunt_sync1_e,   	//hunt for the 1st sync char 
	  hunt_sync2_e,	    //hunt for the 2nd sync char (double sync mode) 
	  sync_hunted_e, 	//sync char(s) was found (on abit aligned basis  
	  external_syndet_watche; //external sync mode: whenever syndet pin  
							 // goes high, set the syndet status bit 
 
always @start_receiver_e 
begin :rcv_blk 
	receive_in_progress = 1; 
	case (modreg[1:0]) 
	2'b00: 
		if (modreg[6] ==0)	// if internal syndet mode ... 
		begin 
			if (dflags[5]) 
				$display("I8251A (%h) at %d : starting internal sync receive",
				instance_id, $time);
				if (dflags[5] && command[7]) 
$display("I8251A (%h) at %d : hunting for syncs", instance_id, $time); 
			   if (modreg[7]==1)	// if enter hunt mode 
				begin  
					if(dflags[5]) 
						$display("I8251A (%h) at %d :receiver waiting on syndet",
 						   instance_id, $time);
					->hunt_sync1_e;	//start search for sync char(s 
					@(posedge syndet); 
					if(dflags[5]) 
$display("I8251A (%h) at %d : receiver DONE waiting on syndet", instance_id, $time); 
				end 
				syn_receive_internal;	//start sync mode receiver 
		end 
		else 
		begin 
			if(dflags[5]) 
				$display("I8251A (%h) at %d : starting external sync receive", instance_id, $time); 
			if(dflags[5] && command[7]) 
				$display("I8251A (%h) at %d : hunting for syncs",  
instance_id, $time);  
			->external_syndet_watche;	// whenever syndet pin goes to 1 
												// set syndet status bit 
			if (command[7]==1) 
			begin:external_syn_hunt_blk 
				fork 
					syn_receive_external;	// assemble chars while waiting 
					@(posedge syndet) 	// after rising edge of syndet 
					@(negedge syndet)		// wait for falling edge 
												// begore starting char assemble 
					disable external_syn_hunt_blk; 
				join 
			end 
 
		syn_receive_external;	// start external sync mode receiving 
		end 
	default:	// if async mode ... 
		begin 
			if(dflags[5]) 
				$display("I8251A (%h) at %d : starting asynchronous receiver", instance_id, $time);
			->break_detect_e;	// start check for rcd=0 too long 
			asyn_receive;	// and start async mode receiver 
		end 
	endcase 
end 
 
	/***** EXTERNAL SYNCHRONOUS MODE RECEIVE *****/ 
task syn_receive_rexternal; 
forever 
	begin 
		repeat(databits)	//Whether in hunt mode or not,assemble a character 
		begin 
			@(posedge rxc_) 
			receivebuf={rcd, receivebuf[7:1]}; 
		end 
		get_and_check_parity;	//receive and check parity bit, if any 
		mark_char_received;	//set rxrdy line, if enalbed 
	end 
endtask 
 
always @(external_syndet_watche)  
	@(posedge rxc_) 
		status[6]=1; 
			/****INTERNAL SYNCHRONOUS MODE RECEIVE ***/ 
			/*   Hunt for the sync char(s)			  */ 
			/*	 (if in synchronous internal sync detect mode) */ 
			/* Syndet is set high when the sync(s) are found */ 
 
always @ (hunt_sysnc1_e)	//search for 1st sync char in the data stream 
begin :sync_hunt_blk 
	while(!(((receivebuf ^ sync1) & syncmask) === 8'b0000_0000)) 
	begin 
		@(posedge rxc_) 
		receivebuf = {rcd, receivebuf[7:1]}; 
	end 
	if ( modreg[7]==0) 	// if double sync mod 
		->hunt_sync2_e;	//check for 2nd sync char directly agter 1 
	else 
		-> sync_hunted_e;	// if single sync mode , sync hunt is complete 
end 
always @ (hunt_sync2_e) 	// find the second synchronous character 
begin : double_sync_hunt_blk 
	repeat(databits) 
	begin 
		@(posedge rxc_) 
		receivebuf={rcd,receivebuf[7:1]}; 
	end 
	if((receivebuf ^ sync2)& syncmask===8'b0000_0000) 
		->sync_hunted_e; // if sync2 followed syn1,sync hunt is complete 
	else 
		->hunt_sync1_e;	//else hunt for sync1 again 
 
	// Note : the data stream [sync1 sync1 sync2] will have sync detected. 
	// Suppose sync1=11001100: 
	// Then [1100 1100 1100 sync2]will NOT be detected . 
	// In general : never let a suffix of sync1 also be a prefix of sync1. 
end 
 
always @ (sync_hunted_e) 
begin :parity_sync_hunt_blk 
	get_and_check_parity; 
	status[6]=1;	//set syndet status bit (sync chars detected ) 
end 
 
task syn_receive_internal; 
forever 
begin 
	repeat(databits)	//no longer in hunt mode so read entire chars and  
	begin             // then look for syncs (instead of on bit boundaries) 
		@(posedge rxc_) 
		receivebuf={rcd,receivebuf[7:1]}; 
	end 
	case (sync_to_receive)  
	2:			// if looking for 2nd sync char ...  
	begin 
		if(((receivebuf ^ sync2) & syncmask)===0) 
		begin 	//... and 2nd sync char is found  
			sync_to_receive =1;	//then look ofr 1st sync (or data) 
			status[6]=1;		// and mark sync detected 
		end 
		else if (((receivebuf ^ sync1) & syncmask)===0) 
		begin 	//... and 1st sync char is found  
			sync_to_receive = 2;	//then look for 2nd sync char 
		end 
		end 
	1: 
	begin 
		if ((( receivebuf ^ sync1) & syncmask) ===0) // ... and 1st sync is found  
		begin 
			if(modreg[7]==0)	//if doulbe sync mode 
				sync_to_receive =2; 	// look for 2nd sync to foll 
			else 
				status[6]=1; 	//else look for 1st or data and mark sync detected  
		end 
		else;	//and data was found , do nothing 
	end 
	endcase 
	get_and_check_parity; 	// receive and check parity bit, if any 
	mark_char_received; 
end 
endtask 


//********************************************************
task syn_receive_external; 
forever 
begin 
// have not found the original programs
end 
endtask

task get_and_check_parity; 
begin 
	receivebuf=receivebuf >> (8-databits); 
	if(modreg[4] == 1) 
	begin 
		@(posedge rxc_) 
		if (( ^receivebuf ^ modreg[5] ^ rcd) != 1) 
			parity_error; 
	end 
end 
endtask 
 
task mark_char_received; 
begin 
	if(command[2]==1) 	// if receiving is enabled 
	begin 
	rxrdy=1;	//set receive read status bit 
	status[1]=1;	//if previous data was not read 
	if(rdatain == 1) 
		overrun_error; // overrun error 
	rdata=receivebuf;	//latch the data 
	rdatain=1;	//mark data as not having been read 
	end 
if(dflags[2]) 
	$display("I8251A (%h) at %d : receive data : %b", instance_id, $time,receivebuf); 
end 
endtask 
 
 
/************* ASYNCHRONOUS MODE RECEIVER ****************/ 
/* CHECK FOR BREAK DETECTION (RCD LOW THROUGH 2 */ 
/* RECEIVE SEQUENCES IN THE ASYNCHRONOUS MODE .*/ 
 
always @ (break_detect_e) 
begin :break_detect_blk 
	#1 /* to be sure break_delay_clk is waiting on break_delay_e 
		after it triggered break_detect_e */ 
	if (rcd==0) 
	begin 
		->break_delay_e; // start + databits +parity +stop bit 
		breakcount_period = 1 +databits + modreg[4] + (tstoptotal!=0); 
		// the number of rxc periods needed for 2 receive sequence  
		breakcount_period  = 2* breakcount_period*baudmx; 
		//if rcd stays low through 2 consecutive  
		// (start ,data,prity ,stop ) sequences ...  
		repeat(breakcount_period) 
			@(posedge rxc_); 
		status[6]=1;	// ... then set break detect (status[6]) high 
	end 
end 
 
always @(break_delay_e)		
begin : break_delay_blk 
	@(posedge rcd )	//but if rcd goes high during that time 
	begin :break_delay_blk   
		disable break_detect_blk; 
		status[6] = 0;	//... then set the break detect low 
		@(negedge rcd ) 	//and when rcd goes low again ... 
		->break_detect_e; 	// ... start the break detection again 
	end 
end 
 
/******** ASYNCHRONOUS MODE RECEIVE TASK ******************/ 
task asyn_receive; 
forever  
	@(negedge rcd) // the receive line went to zero, maybe a start bit 
	begin 
		rbaudcnt = baudmx /2; 
		if (baudmx == 1) 
			rbaudcnt=1; 
		repeat(rbaudcnt) @(posedge rxc_); // after half a bit ... 
		if(rcd == 0)	//if it is still a start bit 
		begin 
			rbaudcnt = baudmx; 
			repeat(databits) // receive the data bits 
			begin 
				repeat(rbaudcnt ) @(posedge rxc_); 
				#1 receivebuf={rcd,receivebuf[7:1]}; 
			end 
			repeat (rbaudcnt) @(posedge rxc_); 
 
				//shift the data to the low part 
			receivebuf = receivebuf >> (8-databits); 
			if(modreg[4]==1)	///if parity is enabled 
			begin 
				if ((^receivebuf ^ modreg[5]^rcd)!=1) 
					parity_error;	//check for a parity error 
				repeat(rbaudcnt) @(posedge rxc_); 
			end 
 
			#1 if (rcd == 0 )	 // if middle of stop bit is 0 
				frame_error;	// frame error (should be 1) 
			 
			mark_char_received; 
		end 
	end 
endtask 
endmodule 
 


[例2]. “商业化”的虚拟模块之二: Intel 8085a 微处理器的行为描述模块

/****************************************************************************
Intel 8085a 微处理器仿真模块的Verilog源代码
注意:作者不能保证本模块的完整和精确,使用本模块者如遇问题一切责任自负
*****************************************************************************/
 
module intel_8085a
        (clock, x2, resetff, sodff, sid, trap, rst7p5, rst6p5, rst5p5, 
         intr, intaff, ad, a, s0, aleff, writeout, readout, s1,iomout, 
         ready, nreset, clockff, hldaff, hold);

    reg [8:1]      dflags;
    initial         dflags = 'b011;
    // diag flags:
    // 1 = trace instructions
    // 2 = trace IN and OUT instructions
    // 3 = trace instruction count

    output
        resetff, sodff, intaff, s0, aleff,
        writeout, readout, s1, iomout, clockff, hldaff;

    inout[7:0] ad, a;

    input
            clock, x2, sid, trap,
            rst7p5, rst6p5, rst5p5,
            intr, ready, nreset, hold;

    reg[15:0]
        pc,        // program counter
        sp,        // stack pointer
        addr;      // address output

    reg[8:0]
        intmask;   // interrupt mask and status

    reg[7:0]
        acc,       // accumulator
        regb,      // general
        regc,      // general
        regd,      // general
        rege,      // general
        regh,      // general
        regl,      // general
        ir,        // instruction
        data;      // data output

    reg
        aleff,     // address latch enable
        s0ff,      // status line 0
        s1ff,      // status line 1
        hldaff,    // hold acknowledge
        holdff,    // internal hold
        intaff,    // interrupt acknowledge
        trapff,    // trap interrupt request
        trapi,     // trap execution for RIM instruction
        inte,      // previous state of interrupt enable flag
        int,       // interrupt acknowledge in progress
        validint,  // interrupt pending
        haltff,    // halt request
        resetff,   // reset output
        clockff,   // clock output
        sodff,     // serial output data
        read,      // read request signal
        write,     // write request signal
        iomff,     // i/o memory select
        acontrol,  // address output control
        dcontrol,  // data output control
        s,         // data source control
        cs,        // sign condition code
        cz,        // zero condition code
        cac,       // aux carry condition code
        cp,        // parity condition code
        cc;        // carry condition code

    wire
        s0 = s0ff & ~haltff,
        s1 = s1ff & ~haltff;

    tri[7:0]
        ad = dcontrol ? (s ? data : addr[7:0]) : 'bz,
        a = acontrol ? addr[15:8] : 'bz;

    tri
        readout = acontrol ? read : 'bz,
        writeout = acontrol ? write : 'bz,
        iomout = acontrol ? iomff : 'bz;

    event
        ec1, // clock 1 event
        ec2; // clock 2 event

    // internal clock generation
    always begin
        @(posedge clock) -> ec1;
        @(posedge clock) -> ec2;
    end

    integer instruction; // instruction count
    initial instruction = 0;

    always begin:run_processor
        #1 reset_sequence;
        fork                                            
            execute_instructions;             // Instructions executed
            wait(!nreset)                     // in parallel with reset  
                @ec2 disable run_processor; // control. Reset will     
        join                                  // disable run_processor   
    end                                       // and all tasks and       
                                              // functions enabled from  
                                              // it when nreset set to 0.

    task reset_sequence;
    begin
        wait(!nreset)
        fork
            begin
                $display("Performing 8085(%m) reset sequence");
                read = 1;
                write = 1;
                resetff = 1;
                dcontrol = 0;
                @ec1 // synchronized with clock 1 event
                    pc = 0;
                    ir = 0;
                    intmask[3:0] = 7;
                    intaff = 1;
                    acontrol = 0;
                    aleff = 0;
                    intmask[7:5] = 0;
                    sodff = 0;
                    trapff = 0;
                    trapi = 0;
                    iomff = 0;
                    haltff = 0;
                    holdff = 0;
                    hldaff = 0;
                    validint = 0;
                    int = 0;
                disable check_reset;
            end
            begin:check_reset
                wait(nreset)               // Check, in parallel with the
                    disable run_processor; // reset sequence, that nreset
            end                            // remains at 0.
        join
        wait(nreset) @ec1 @ec2 resetff = 0;

⌨️ 快捷键说明

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