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

📄 buscon.v

📁 键盘和USB与PC机的接口程序
💻 V
📖 第 1 页 / 共 2 页
字号:


//
// BUSCON.V
//
// Bus Controller for PopCorn V3 
// This module interfaces to the bus.
// CS, RD, WR are generated here. 
//


`include "inc.h"
`timescale 1 ns / 100 ps


module buscon (	// system
				sys_clk,
				sys_rst_l,
                boot_l,
				// to/from memory 
				data_bus_in,
				addx_bus,
				ready_h,
				code_cs_l,
                bus_memH,
				sram_cs0_l,
				sram_cs1_l,
				code_rd_l,
				code_wr_l,
				data_bus_wrL,
				// command/handshake
				buscon_startH,
				buscon_cmd,
				buscon_cmdIN,
				buscon_doneH,
				reg_opl,
				reg_oplo,
				reg_ophi,
                copy_completedH,
                bus_cycle_is_portH,
				interrupt_pendingH ,
				add2_to_PCH,
				// to/from datapath
				d_bus,
				reg_pc,
                reg_ax,
                reg_bx,

				//debug
				reg_sp,
				SP_change,
				sp_delta

			);

// ********************************************
//
//    INPUT / OUTPUT DECLARATION
//
// ********************************************
// system
input			sys_clk;
input			sys_rst_l;
input           boot_l;
// to/from memory 
input 	[7:0]	data_bus_in;
output	[`AW-1:0]addx_bus;
input			ready_h;
output			code_cs_l;
output          bus_memH;
output			sram_cs0_l;
output			sram_cs1_l;
output			code_rd_l;
output			code_wr_l;		
output			data_bus_wrL;
// command/handshake
input			buscon_startH;
input	[8:0]	buscon_cmd;
input	[8:0]	buscon_cmdIN;
output			buscon_doneH;
output	[7:0]	reg_opl;
output	[7:0]	reg_oplo;
output	[`AW-9:0]reg_ophi;
output          copy_completedH;
input           bus_cycle_is_portH;
input			interrupt_pendingH;
input			add2_to_PCH;
// to/from datapath
output	[`AW-1:0]reg_pc;
output	[`AW-1:0]d_bus;
input   [7:0]   reg_ax;
input   [7:0]   reg_bx;

// debug
output	[`SW-1:0]	reg_sp;
output	[`SW-1:0]	sp_delta;
output				SP_change;


parameter	HI = 1'b1;
parameter	LO = 1'b0;
parameter   X  = 1'bx;

parameter	WAIT_4_REQ     = 2'b00,
			ASSERT_RDWR    = 2'b01,
			WAIT_4_READY   = 2'b11;


reg		[1:0]	buscon_state;
reg				cs_l;
reg				wr_l;
reg				rd_l;
reg				data_bus_wrL;
reg				buscon_doneH;
reg				SP_decH;
reg				PC_loadH;
reg				PC_incH;
reg		[7:0]	reg_oplIn;
wire	[7:0]	reg_opl;
reg		[7:0]	reg_oplo;
reg		[`AW-9:0]reg_ophi;
reg		[`AW-1:0]reg_pc;
reg		[`SW-1:0]reg_sp;
reg		[`AW-1:0]addx_bus;
reg             copy_completedH;
reg             sram_cs0_l;
reg             code_cs_l;
reg  			bus_wrH;

reg             next_wait_state;
reg             wait_state;
reg             readyIN_h;
reg     [1:0]   wait_state_cntr;
reg             inc_wait_state_cntr;


wire			SP_incINH;
wire			SP_decINH;
wire			PC_incINH;
wire			PC_loadINH;
wire			PC_incrementH;
wire	[2:0]	addx_mux;
wire			writeopH;
wire	[`AW-1:0]d_bus;
wire            copy_thresholdH;
wire            anyCS_l;
wire            LOAD_OPL_H;
wire            LOAD_OPLO_H;
wire            LOAD_OPHI_H;
wire            bus_memH;
reg            reg2load_opl;
reg            reg2load_oplo;
reg            reg2load_ophi;


// ****************************************************************
//  
//  BUS SIGNAL GENERATION
//
//  Generates CS, RD and WR
//
// ****************************************************************

assign code_rd_l = rd_l;
assign code_wr_l = wr_l;

//
// bus_cycle_is_portH  is a signal from sequencer (seq.v)
// which asserts high or low ONLY during the DATA READ/WRITE
// bus cycles.  That is, it is always asserted low during 
// opcode fetch cycle.  This signal when high, means that
// data is to be read from port memory, when low to be read from
// main memory space

// SRAM_CS1_L
// Asserts low when Addx[MSB] = 1, and the 
// bus cycle is active
assign sram_cs1_l = ( cs_l | ~addx_bus[`AW-1] ) | bus_cycle_is_portH;
//assign sram_cs1_l = ~addx_bus[`AW-1];

assign bus_memH = cs_l | ~bus_cycle_is_portH;

// CODE_CS_L and SRAM_CS0_L
//
// ADDRESS DECODE:
//      code_cs_l:  asserted on the lower 32Kb of addx space
//                    when boot_l option is not used
//      sram_cs0_lL asserted on the lower 32Kb of addx space
//                    when boot_l option is used.
//      sram_cs1_l: asserted on the upper 32Kb of addx space
//
//
//
always @(boot_l or cs_l or addx_bus or copy_completedH or 
         bus_wrH or bus_cycle_is_portH)
  case ({boot_l,copy_completedH})
    // normal mode, when copying from FLASH->SRAM is
    // not requested.  In this case, sram_cs0_l is not
    // used
    2'b10,
    2'b11: begin 
            code_cs_l  = (addx_bus[`AW-1] | bus_cycle_is_portH) | cs_l;
            sram_cs0_l = 1'b1;
           end
    // DURING COPYING 
    2'b00: begin
            code_cs_l  =  bus_wrH  | cs_l;
            sram_cs0_l = ~bus_wrH  | cs_l;
           end
    // AFTER COPYING IS DONE
    2'b01: begin    
            code_cs_l  = 1'b1;
            sram_cs0_l = addx_bus[`AW-1] | bus_cycle_is_portH  | cs_l;
           end
    default: begin
            code_cs_l  = 1'bx;
            sram_cs0_l = 1'bx;
           end
  endcase




// ********************************************
//
// BUSCONTROLLER (BUSCON)
// SEQUENCING COMMAND
// Decode the command in to control sequences
//
// ********************************************
//
// 
// CMD[9:7]  addx     => {OPLHI,OPLO}=0  PC=1  SP=2  INT_VEC_LO=3  INT_VEC_HI=4   MEM_COPY=5
// CMD[1:0]  reg2load => none=0  load_ophiH=1  load_oploH=2  load_oplH=3 
//
//                    9:7   6         5       4      3      2      1:0
// 					  addx  pc_preInc pc_load pc_inc sp_dec sp_inc reg2load
//
//
always @(buscon_cmd)
begin

  reg2load_ophi = 1'b0;
  reg2load_oplo = 1'b0;
  reg2load_opl  = 1'b0;

  case (buscon_cmd[1:0])
    2'b01: reg2load_ophi = 1'b1;
    2'b10: reg2load_oplo = 1'b1;
    2'b11: reg2load_opl  = 1'b1;
    default: ;
  endcase
end

// LOAD OPERAND HI register
// The current bus cycle will read a byte from the
// address bus and place it to reg_ophi
assign LOAD_OPHI_H = reg2load_ophi;

// LOAD OPERAND LOW register
// The current bus cycle will read a byte from the
// address bus and place it to reg_oplo
assign LOAD_OPLO_H = reg2load_oplo;

// LOAD OPCODE LATCH REGISTER
// The current bus cycle will read a byte from the
// address bus and place it to reg_oplo
assign LOAD_OPL_H = reg2load_opl;

// Pre-Increment SP.
// The incrementing of the stack needs to take place
// at the same time as CS and RD/WR is assrted.
// the only way to do this is to assert SP_incINH
// at the same cycle as buscon_startH.  By protocol,
// buscon_startH will be asserted only for 1 tick.
assign SP_incINH    = buscon_cmdIN[2] & buscon_startH;

// Post-Decrement SP
// The SP will be decremented by 1 at the completion
// of the current bus cycle
assign SP_decINH    = buscon_cmd[3];

// Post-Increment PC.  The PC is incremented by 1
// after the bus cycles is completed.
assign PC_incINH    = buscon_cmd[4];

// Post-Load PC.
// The PC is loaded with the data presented at the
// d_bus at the completion of the current bus
// cycle
assign PC_loadINH   = buscon_cmd[5];


// This steers the address bus with the correct
// source of address:
// 000  d_bus
// 001  reg_pc
// 010  reg_sp      
// 011  16'h0010    the low addx of interrupt vector
// 100  16'h0011    the high addx of interrupt vector
//
// This is a cheap way to generate a "latch" equivalant.
// addx_mux will be stable as soon as buscon_cmdIN becomes
// stable.
assign addx_mux     = buscon_cmd[8:6];

// when neither opl, oplo nor ophi are request to
// be loaded, this means that we're doing a write
// We use the buscon_cmdIN instead of buscon_cmd
// because it is available 1 tick ahead.  
assign writeopH     = ~|buscon_cmdIN[1:0];  

// bus_wr is stable over the current bus
// transfer and r emains so until the next
// bus transfer.  It indcates whether the 
// bus cycles is write or read.
always @(posedge sys_clk or negedge sys_rst_l)
  if (~sys_rst_l)
    bus_wrH <= 1'b0;
  else if (buscon_startH)
    bus_wrH <= writeopH;



//
// S T A T E   M A C H I N E
//  
always @(posedge sys_clk or negedge sys_rst_l)
  if (~sys_rst_l) begin

⌨️ 快捷键说明

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