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

📄 buscon.v

📁 键盘和USB与PC机的接口程序
💻 V
📖 第 1 页 / 共 2 页
字号:
        cs_l         <= HI;
        rd_l         <= HI;
        wr_l         <= HI;
		data_bus_wrL <= HI;
		PC_loadH     <= LO;
		PC_incH      <= LO;
	 	SP_decH      <= LO;
		buscon_doneH <= LO;
        buscon_state <= WAIT_4_REQ;
 end else

       case (buscon_state)
	
		// 
		// WAIT_4_REQ
		// wait for any read or write requests
        WAIT_4_REQ: begin
		  // do the below whenver we're in this state
		  begin
			 buscon_doneH 	<= LO;
			 PC_loadH 		<= LO;
		     PC_incH  		<= LO;
			 SP_decH  		<= LO;
			 data_bus_wrL   <= HI;	    
          end
          if (buscon_startH) begin
             cs_l         <= LO;
			 buscon_state <= ASSERT_RDWR;
          end else begin
  			 cs_l 			<= HI;
		  end
		end

		//
		// Hold the Bus in this state for 1 tick
		//
		ASSERT_RDWR:	begin
             rd_l         <= bus_wrH;
             wr_l         <= ~bus_wrH;
			 data_bus_wrL <= ~bus_wrH;	    // drive data bus with c_bus							
			 buscon_state <= WAIT_4_READY;
		end


		//
		// WAIT_4_READY
		//
		// Sample for wait-state request
		// a wait state request is if readyH
		// is not 1 (i.e. not ready)
		//
        WAIT_4_READY: begin
          // if any of the ready_h or readyIN_h is low
          // (i.e not ready) wait until it gets high
          if (readyIN_h & ready_h ) begin
			 // Deassert most of the bus signals
			 begin
			 	rd_l         <= HI;
			 	wr_l         <= HI;
             	buscon_doneH <= HI;
			 end
			 // Update PC/SP.  This occurs on the next cycle
			 // due to the piping 
			 begin
				PC_loadH <= PC_loadINH;
			    PC_incH  <= PC_incINH;
	 			SP_decH  <= SP_decINH;
			 end
             buscon_state <= WAIT_4_REQ;
          end
        end
        		
     endcase

//
// PC
// Program Counter
//
// The PC is a post-increment design.
// That is, it increments afre the current bus-cycle
// is over.  The post-incrementing is by 1 usually,
// but there are times it is incremented by 2.
// This occurs when a failed branch
// opcode is detected.  In this case, the next opcode
// to be fetched is branch + 3.  
//
assign PC_incrementH = PC_incH | add2_to_PCH;
assign copy_thresholdH = reg_pc[`K-1] & ~boot_l & ~copy_completedH;
//
// This dictates how much the PC is to be incremented by.
// In the event of a failed branch-condition, the PC needs
// to be incremented by 2.  At all other cases, the PC
// increments simply by 1
wire [`AW-1:0] pc_delta;
assign pc_delta = add2_to_PCH ? 2 : 1;
always @(posedge sys_clk or negedge sys_rst_l)
	if (~sys_rst_l)
		reg_pc <= {`AW{1'b0}};   // the reset value must be all 0's 
	else 
    // parallel statement
    begin
        if (copy_thresholdH) reg_pc <= {`AW{1'b0}}; 
		// load 
        if (PC_loadH)        reg_pc <= d_bus;       
		// post inctrement
        if (PC_incrementH)   reg_pc <= reg_pc + pc_delta;  
    end


//
// SP
//
// Stack Pointer is always initialized to 0xFFFF (the top
// of PC1's address space).
// For PUSH the stack is a post decrementer, that is, 
// it pushes first then decrement.  
// For POPs it increments first, then reads.
// The stack pointer is only 12 bits long.
// 
wire    SP_change;
wire    [`SW-1:0] sp_delta;
assign SP_change = SP_incINH | SP_decH;

// This mux select between +1 or -1.
// This allows the use of only 1 adder
assign sp_delta = SP_incINH ? {{`SW-1{1'b0}},1'b1} : {`SW{1'b1}};

always @(posedge sys_clk or negedge sys_rst_l)
	if (~sys_rst_l)
		reg_sp <= {`SW{1'b1}};		// default reset value of sp is 0xFFFF
	else 
//        if (SP_change) reg_sp <= reg_sp + sp_delta;
		if (SP_incINH) reg_sp <= reg_sp + 1;
		else if (SP_decH) reg_sp <= reg_sp -1;


//
// CMD[9:7]  addx     => {OPLHI,OPLO}=0  PC=1  SP=2  INT_VEC_LO=3  INT_VEC_HI=4   MEM_COPY=5
//
//
// This mux selectes the source of the address
// during the bus_cycle
//
//
always @(addx_mux or reg_pc or reg_sp or d_bus or reg_ax or reg_bx)
	case (addx_mux)
		3'b000: addx_bus   = d_bus;
		3'b001: addx_bus   = reg_pc;   // during MEM_COPY also use PC
		3'b010: addx_bus   = {{(16-`SW){1'b1}},reg_sp}; // SP is only 11 bits 
		3'b011: addx_bus   = 16'h0010; // int vector Low  addx        
        3'b100: addx_bus   = 16'h0011; // int vector High addx
        3'b101: addx_bus   = {reg_bx,reg_ax};
		default: addx_bus  = 16'hxxxx; 
	endcase 


//
// OPL  
//
// Opcode Holding Register 8 bit
// This register holds the opcode fetched during the
// opcode-fetch cycle.
// Note that it is synchronous to the RISING EDGE OF
// RD signal.
//
always @(posedge code_rd_l or negedge sys_rst_l)
   if (~sys_rst_l) reg_oplIn <= 8'h00;
   else 
     	if (LOAD_OPL_H) reg_oplIn <= data_bus_in;
		else reg_oplIn <= reg_oplIn; 

// when we're processing interrupt, no new opcode
// is loaded, thus the old opcode is still in opcode-reg
// and can messup the interrupt cycle. Thus, we clear it
// to 0.
assign reg_opl = interrupt_pendingH ? 0 : reg_oplIn;


//
// OPLO
//
// This register hold the low byte operand fetched
// from the memory.
// This regsiter holds the low byte of address
// or data from stack or from memory.
// Note that this is LEVEL TRIGGERED LATCH.
// this is because this register is the critical
// path for all ALU operations.  
//
always @(posedge code_rd_l or negedge sys_rst_l)
  if (~sys_rst_l) reg_oplo = 8'h00;    
  else 
      if (LOAD_OPLO_H) reg_oplo = data_bus_in;
      else reg_oplo = reg_oplo;




//
// OPHI
//
// This register hold the low byte operand fetched
// from the memory.
// This register hold the high byte of address.
// Note that it is synchronous to the RISING EDGE OF
// RD signal.
//
always @(posedge code_rd_l or negedge sys_rst_l)
  if (~sys_rst_l) reg_ophi = {`AW-9{1'b0}};  
  else 
    if (LOAD_OPHI_H ) reg_ophi = data_bus_in;
    else reg_ophi = reg_ophi;


assign d_bus={reg_ophi,reg_oplo};



//
// copy_completedH gets to be set and remains set
// when reg_pc reaches half of the address space
// and boot_l is set low. Until then, it is low.
// Use this signal in conjunction with boot_l
// to qualify copying status.
//
always @(posedge sys_clk or negedge sys_rst_l)
  if (~sys_rst_l)
    copy_completedH <= 1'b0;
  else if (~copy_completedH)
    copy_completedH <= reg_pc[`K-1] & ~boot_l;
    


// **************************************************************
//
// I N T E R N A L    B U S Y    G E N E R A T I O N
//
// Internal readyIN_h generation.
// During the FLASH->SRAM copying process,
// we need to insert a number of the wait state so that
// the copy from the slow FLASH to SRAM can be done
// even with slow FLASH devices, yet running with high
// clock speed (>25MHz)
//
// **************************************************************

assign anyCS_l = sram_cs0_l & code_cs_l;

// State Machine State Definition
`define wait_to_start     1'b0
`define wait_to_complete  1'b1

//
// Wait-State Generating State Machine
//
always @(anyCS_l or wait_state_cntr or 
         wait_state or copy_completedH or boot_l) 
  begin

    // default values    
    inc_wait_state_cntr = 0;
    readyIN_h = 1'b1;

    case (wait_state)
      // In this state, wait for the right point of
      // the bus-cycle to insert the first wait
      // cycle.  Insert the wait state only if, any of
      // the CS are asserted and copy_completedH is 
      // still low.  This signal will be low until the
      // copy process is completed.  And boot_l is low,
      // that is, copy is requested.
      `wait_to_start: begin
            if (~anyCS_l & ~copy_completedH & ~boot_l) begin
                next_wait_state = `wait_to_complete;
                inc_wait_state_cntr = 1'b1; 
                // deassert readyINH_h (not ready, i.e. busy)
                // only if copying is requested.
                readyIN_h = boot_l;
            end
            else begin
                next_wait_state = `wait_to_start;
            end
       end

      // In this state keep readyINH_h deasserted (i.e.
      // not ready) while the wait-state counter has
      // not reached the limit.
      `wait_to_complete:
            if (wait_state_cntr == 2'b11) begin
               next_wait_state = `wait_to_start;
            end
            else begin
                next_wait_state = `wait_to_complete;
                inc_wait_state_cntr = 1'b1; 
                readyIN_h = 1'b0;
            end

       default: begin
                next_wait_state = 1'bx;
                inc_wait_state_cntr = 1'bx; 
                readyIN_h = 1'bx;
       end
    endcase
    
  end

// Next State State Assigment
always @(posedge sys_clk or negedge sys_rst_l)
  if (~sys_rst_l) wait_state <= `wait_to_start;
  else            wait_state <= next_wait_state;
     
// Counter which is used to generated the wait-state
// ticks.
always @(posedge sys_clk or negedge sys_rst_l)
  if (~sys_rst_l)
    // reset the counter
    wait_state_cntr <= 0;           
  else 
    // count up only if allowed
    if (inc_wait_state_cntr)
      wait_state_cntr <= wait_state_cntr + 1;
 



endmodule

⌨️ 快捷键说明

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