/******************************************************************************/
/* */
/* Copyright (c) 1999 Sun Microsystems, Inc. All rights reserved. */
/* */
/* The contents of this file are subject to the current version of the Sun */
/* Community Source License, microSPARCII ("the License"). You may not use */
/* this file except in compliance with the License. You may obtain a copy */
/* of the License by searching for "Sun Community Source License" on the */
/* World Wide Web at http://www.sun.com. See the License for the rights, */
/* obligations, and limitations governing use of the contents of this file. */
/* */
/* Sun Microsystems, Inc. has intellectual property rights relating to the */
/* technology embodied in these files. In particular, and without limitation, */
/* these intellectual property rights may include one or more U.S. patents, */
/* foreign patents, or pending applications. */
/* */
/* Sun, Sun Microsystems, the Sun logo, all Sun-based trademarks and logos, */
/* Solaris, Java and all Java-based trademarks and logos are trademarks or */
/* registered trademarks of Sun Microsystems, Inc. in the United States and */
/* other countries. microSPARC is a trademark or registered trademark of */
/* SPARC International, Inc. All SPARC trademarks are used under license and */
/* are trademarks or registered trademarks of SPARC International, Inc. in */
/* the United States and other countries. Products bearing SPARC trademarks */
/* are based upon an architecture developed by Sun Microsystems, Inc. */
/* */
/******************************************************************************/
/***************************************************************************
****************************************************************************
***
*** Program File: @(#)promif.v
***
****************************************************************************
****************************************************************************/
// derived from Phoenix file version:
// @(#)promif.v 09.12.95
// promif.v Generic FlashProm interface
//
module promif
(
ss_scan_mode,
promif_scan_in,
promif_scan_out,
bm_sel,
gclk_1st_phase,
ss_reset,
ss_clock,
aen_in,
// falcon_exists,
rom_speed,
mc_mwe_l,
s_reply,
ab,
dbus_out,
dbus_in,
dbus_oe,
dbus_oe_standby,
dbus2pad_eo,
dbus2pad_out,
dbus2pad_in,
pcic_afxs_dbout,
pcic_afxm_dbout,
pcic_db_oen,
pcic_afxm_db_oen,
memif_mempar,
mpar_out1,
mpar_out2,
w_b_mempar_out,
pad_mempar_in,
w_b_mempar_in,
memif_ab_out,
memif_memaddr_out,
pcic_ab_out,
pcic_ab_oen,
w_ab_out,
w_mc_memaddr,
prom_p_reply,
rom_addr,
rom_oe_l,
rom_we_l,
rom_cs_l
) ;
input ss_scan_mode
;
input promif_scan_in
;
output promif_scan_out
;
input [1:0] bm_sel
;
input gclk_1st_phase
;
input ss_reset
;
input ss_clock
;
input aen_in
;
wire falcon_exists
= 1'b1;
input [3:0] rom_speed
;
input mc_mwe_l
;
input s_reply
;
input [14:0] ab
;
input [63:0] dbus_out
;
output [63:0] dbus_in
;
input dbus_oe
;
input dbus_oe_standby
;
output dbus2pad_eo
;
output [63:0] dbus2pad_out
;
input [63:0] dbus2pad_in
;
input [63:0] pcic_afxs_dbout
;
input [63:0] pcic_afxm_dbout
;
input pcic_db_oen
;
input pcic_afxm_db_oen
;
input [1:0] memif_mempar
;
input [1:0] mpar_out1
;
input [1:0] mpar_out2
;
output [1:0] w_b_mempar_out
;
input [1:0] pad_mempar_in
;
input [1:0] w_b_mempar_in
;
input [14:12] memif_ab_out
;
input [11:0] memif_memaddr_out
;
input [14:0] pcic_ab_out
;
input pcic_ab_oen
;
output [14:12] w_ab_out
;
output [11:0] w_mc_memaddr
;
output [1:0] prom_p_reply
;
output [23:0] rom_addr
;
output rom_oe_l
;
output rom_we_l
;
output rom_cs_l
;
wire sel_8bit
= (bm_sel == 2'b01) ? 1 : 0 ;
reg sync_t1
, sync_t2
;
always@(posedge ss_clock)
sync_t1 <= #1 gclk_1st_phase ;
always@(posedge ss_clock)
sync_t2 <= #1 sync_t1 ;
reg [28:3] addr_reg
;
reg [63:0] prom_data
;
reg [4:0] state
, nstate
;
parameter GET_HI_ADDR = 6'h0 ;
parameter GET_LO_ADDR = 6'h1 ;
parameter START_READ_L_BYTE1 = 6'h2 ;
parameter READ_WAIT_L_BYTE1 = 6'h3 ;
parameter START_READ_L_BYTE2 = 6'h4 ;
parameter READ_WAIT_L_BYTE2 = 6'h5 ;
parameter START_READ_L_BYTE3 = 6'h6 ;
parameter READ_WAIT_L_BYTE3 = 6'h7 ;
parameter START_READ_L_BYTE4 = 6'h8 ;
parameter READ_WAIT_L_BYTE4 = 6'h9 ;
parameter START_READ_H_BYTE1 = 6'ha ;
parameter READ_WAIT_H_BYTE1 = 6'hb ;
parameter START_READ_H_BYTE2 = 6'hc ;
parameter READ_WAIT_H_BYTE2 = 6'hd ;
parameter START_READ_H_BYTE3 = 6'he ;
parameter READ_WAIT_H_BYTE3 = 6'hf ;
parameter START_READ_H_BYTE4 = 6'h10 ;
parameter READ_WAIT_H_BYTE4 = 6'h11 ;
parameter READ_DONE_H = 6'h12 ;
parameter START_WRITE_L = 6'h13 ;
parameter WRITE_WAIT_L = 6'h14 ;
parameter WRITE_DONE_L = 6'h15 ;
parameter START_WRITE_H = 6'h16 ;
parameter WRITE_WAIT_H = 6'h17 ;
parameter WRITE_DONE_H = 6'h18 ;
parameter START_READ_BYTE = 6'h19 ;
parameter READ_WAIT_BYTE = 6'h1a ;
parameter READ_DONE_BYTE = 6'h1b ;
reg low_word_only
;
spares promif_spares();
wire prom_read_data
;
wire [63:0] dbus_in =
//prom_p_reply[0] ? prom_data[63:0] :
prom_read_data ? prom_data[63:0] :
pcic_db_oen ? pcic_afxs_dbout : dbus2pad_in[63:0] ;
wire [63:0] dbus2pad_out =
(state == WRITE_WAIT_H) ?
prom_data[63:0] :
(state == WRITE_WAIT_L) ?
prom_data[63:0] :
pcic_db_oen ?
pcic_afxm_dbout : dbus_out[63:0] ;
wire dbus2pad_eo = rom_oe_l & (dbus_oe |
// drive for pcic afx master only (not pcic afx slave)
// add standyb to avoid crowbar
dbus_oe_standby |
pcic_afxm_db_oen |
(state == WRITE_WAIT_H) |
(state == WRITE_WAIT_L)) ;
// substitue afx slave parity if afx slave is driving bus (receive side )
// don't actually drive the bus, just return the data
wire [1:0] w_b_mempar_in = pcic_db_oen ? mpar_out1 : pad_mempar_in;
// substitue afx master parity if afx master driving bus (drive to memory)
wire [1:0] w_b_mempar_out = pcic_db_oen ? mpar_out2 : memif_mempar;
// now select afxmaster address if enabled, otherwise memif address
wire [14:12] w_ab_out = pcic_ab_oen ? pcic_ab_out[14:12] : memif_ab_out;
wire [11:0] w_mc_memaddr = pcic_ab_oen ? pcic_ab_out[11:0] : memif_memaddr_out;
always@(posedge ss_clock)
if (ss_reset)
state <= #1 GET_HI_ADDR ;
else if (sync_t2)
state <= #1 nstate ;
wire rom_access
= ~addr_reg[28] ;
reg [3:0] counter
;
wire countdone
= counter == 'h0 ;
wire [3:0] rom_speed_ld
= rom_speed[3:0] |
{2{(rom_speed == 'h0) | (rom_speed == 'h1)}} ;
always@(posedge ss_clock)
if (ss_reset)
counter <= #1 4'h0 ;
else if (sync_t2)
counter <= #1
(state == GET_HI_ADDR) ? 'h0 :
( (state == START_READ_L_BYTE1) |
(state == START_READ_L_BYTE2) |
(state == START_READ_L_BYTE3) |
(state == START_READ_L_BYTE4) ) ? rom_speed_ld :
( (state == START_READ_H_BYTE1) |
(state == START_READ_H_BYTE2) |
(state == START_READ_H_BYTE3) |
(state == START_READ_H_BYTE4) ) ? rom_speed_ld :
(state == START_READ_BYTE) ? rom_speed_ld :
(state == START_WRITE_L) ? rom_speed_ld :
(state == START_WRITE_H) ? rom_speed_ld :
counter - 1 ;
wire aen
= aen_in & falcon_exists ;
// Changed dblword here since now we can have 8 bit mode also
//wire dblword = ab[12] ;
// change all operations to be doubleword so that loads of any size
// will function. The shifting etc. is done by the herbulator.
// all non word / double word accesses in 32 bit mode will be converted
// to doublewords
// all non byte operations in 8 bit mode are converted to doubleword
wire dblword
= ((sel_8bit & ab[14]
| (~sel_8bit & ~(ab[14] & ~ab[12] & ab[11]))) & mc_mwe_l)
| (~mc_mwe_l & ab[12]);
always@(state or aen or rom_access or s_reply or mc_mwe_l or
dblword or countdone or sel_8bit)
casez ({state,aen,s_reply,mc_mwe_l,rom_access,dblword,countdone,sel_8bit})
{GET_HI_ADDR, 7'b10?????}: nstate = GET_LO_ADDR ;
{GET_HI_ADDR, 7'b11111?1},
{GET_LO_ADDR, 7'b11111?1}: nstate = START_READ_L_BYTE1 ;
{GET_HI_ADDR, 7'b11111?0},
{GET_LO_ADDR, 7'b11111?0}: nstate = START_READ_L_BYTE4 ;
{GET_HI_ADDR, 7'b11110?1},
{GET_LO_ADDR, 7'b11110?1}: nstate = START_READ_BYTE ;
{GET_HI_ADDR, 7'b11110?0},
{GET_LO_ADDR, 7'b11110?0}: nstate = START_READ_H_BYTE4 ;
{GET_HI_ADDR, 7'b1101??1},
{GET_LO_ADDR, 7'b1101??1}: nstate = START_WRITE_H ;
{GET_HI_ADDR, 7'b11011?0},
{GET_LO_ADDR, 7'b11011?0}: nstate = START_WRITE_L ;
{GET_HI_ADDR, 7'b11010?0},
{GET_LO_ADDR, 7'b11010?0}: nstate = START_WRITE_H ;
// read BYTE only
{START_READ_BYTE, 7'b??????1},
{READ_WAIT_BYTE, 7'b?????01}: nstate = READ_WAIT_BYTE ;
{READ_WAIT_BYTE, 7'b?????11}: nstate = READ_DONE_BYTE ;
// read LOW addr bytes
{START_READ_L_BYTE1, 7'b??????1},
{READ_WAIT_L_BYTE1, 7'b?????01}: nstate = READ_WAIT_L_BYTE1 ;
{READ_WAIT_L_BYTE1, 7'b?????11}: nstate = START_READ_L_BYTE2 ;
{START_READ_L_BYTE2, 7'b??????1},
{READ_WAIT_L_BYTE2, 7'b?????01}: nstate = READ_WAIT_L_BYTE2 ;
{READ_WAIT_L_BYTE2, 7'b?????11}: nstate = START_READ_L_BYTE3 ;
{START_READ_L_BYTE3, 7'b??????1},
{READ_WAIT_L_BYTE3, 7'b?????01}: nstate = READ_WAIT_L_BYTE3 ;
{READ_WAIT_L_BYTE3, 7'b?????11}: nstate = START_READ_L_BYTE4 ;
{START_READ_L_BYTE4, 7'b???????},
{READ_WAIT_L_BYTE4, 7'b?????0?}: nstate = READ_WAIT_L_BYTE4 ;
{READ_WAIT_L_BYTE4, 7'b?????11}: nstate = START_READ_H_BYTE1 ;
{READ_WAIT_L_BYTE4, 7'b?????10}: nstate = START_READ_H_BYTE4 ;
// read HIGH addr bytes
{START_READ_H_BYTE1, 7'b??????1},
{READ_WAIT_H_BYTE1, 7'b?????01}: nstate = READ_WAIT_H_BYTE1 ;
{READ_WAIT_H_BYTE1, 7'b?????11}: nstate = START_READ_H_BYTE2 ;
{START_READ_H_BYTE2, 7'b??????1},
{READ_WAIT_H_BYTE2, 7'b?????01}: nstate = READ_WAIT_H_BYTE2 ;
{READ_WAIT_H_BYTE2, 7'b?????11}: nstate = START_READ_H_BYTE3 ;
{START_READ_H_BYTE3, 7'b??????1},
{READ_WAIT_H_BYTE3, 7'b?????01}: nstate = READ_WAIT_H_BYTE3 ;
{READ_WAIT_H_BYTE3, 7'b?????11}: nstate = START_READ_H_BYTE4 ;
{START_READ_H_BYTE4, 7'b???????},
{READ_WAIT_H_BYTE4, 7'b?????0?}: nstate = READ_WAIT_H_BYTE4 ;
{READ_WAIT_H_BYTE4, 7'b?????1?}: nstate = READ_DONE_H ;
// write LOW addr bytes
{START_WRITE_L, 7'b???????},
{WRITE_WAIT_L, 7'b?????0?}: nstate = WRITE_WAIT_L ;
{WRITE_WAIT_L, 7'b?????1?}: nstate = WRITE_DONE_L ;
{WRITE_DONE_L, 7'b???????}: nstate = START_WRITE_H ;
// write HIGH addr bytes
{START_WRITE_H, 7'b???????},
{WRITE_WAIT_H, 7'b?????0?}: nstate = WRITE_WAIT_H ;
{WRITE_WAIT_H, 7'b?????1?}: nstate = WRITE_DONE_H ;
default: nstate = GET_HI_ADDR ;
endcase
reg [2:0] wr_bytes_2to0
;
always@(posedge ss_clock)
if (ss_reset)
{low_word_only,addr_reg[28]} <= #1 2'b01 ;
else if (aen & ~s_reply & ~ab[0] & sync_t2)
addr_reg[28:14] <= #1 {ab[0],ab[14:1]};
else if (aen & ~s_reply & ab[0] & sync_t2)
addr_reg[28] <= #1 1'b1 ;
// Changed low_word_only to correctly access during 8bit mode
else if (aen & s_reply & rom_access & sync_t2 & (sel_8bit == 0))
{wr_bytes_2to0,low_word_only,addr_reg[13:3]} <= #1
{ab[13:11],(ab[14:11]==4'h9),ab[10:0]};
else if (aen & s_reply & rom_access & sync_t2 & (sel_8bit == 1))
{wr_bytes_2to0,low_word_only,addr_reg[13:3]} <= #1
{ab[13:11],(ab[14:13]==2'b00),ab[10:0]};
reg [23:0] rom_addr ;
always@(posedge ss_clock)
if ((nstate == START_READ_L_BYTE2) & sync_t2 & (sel_8bit == 1))
prom_data[63:56] <= #1 dbus2pad_in[7:0] ;
else
if ((nstate == START_READ_L_BYTE3) & sync_t2 & (sel_8bit == 1))
prom_data[55:48] <= #1 dbus2pad_in[7:0] ;
else
if ((nstate == START_READ_L_BYTE4) & sync_t2 & (sel_8bit == 1))
prom_data[47:40] <= #1 dbus2pad_in[7:0] ;
else
if ((nstate == START_READ_H_BYTE1) & sync_t2 & (sel_8bit == 1))
prom_data[39:32] <= #1 dbus2pad_in[7:0] ;
else
if ((nstate == START_READ_H_BYTE4) & sync_t2 & (sel_8bit == 0))
prom_data[63:32] <= #1 dbus2pad_in[31:0] ;
else
if ((nstate == READ_DONE_H) & low_word_only & sync_t2 & (sel_8bit == 0))
prom_data[63:0] <= #1 {dbus2pad_in[31:0],
dbus2pad_in[31:0]} ;
else
if ((nstate == START_READ_H_BYTE2) & sync_t2 & (sel_8bit == 1))
prom_data[31:24] <= #1 dbus2pad_in[7:0] ;
else
if ((nstate == START_READ_H_BYTE3) & sync_t2 & (sel_8bit == 1))
prom_data[23:16] <= #1 dbus2pad_in[7:0] ;
else
if ((nstate == START_READ_H_BYTE4) & sync_t2 & (sel_8bit == 1))
prom_data[15:8] <= #1 dbus2pad_in[7:0] ;
else
if ((nstate == READ_DONE_H) & sync_t2 & (sel_8bit == 1))
prom_data[7:0] <= #1 dbus2pad_in[7:0] ;
else
if ((nstate == READ_DONE_H) & ~low_word_only & sync_t2 & (sel_8bit == 0))
prom_data[31:0] <= #1 dbus2pad_in[31:0] ;
else
if ((nstate == READ_DONE_BYTE) & sync_t2 & (sel_8bit == 1))
prom_data[63:0] <= #1 {8{dbus2pad_in[7:0]}} ;
else
if (( state == START_WRITE_L) & sync_t2 & (sel_8bit == 0))
prom_data[63:0] <= #1 {dbus_out[31:0],dbus_out[63:32]} ;
else
if (( state == START_WRITE_H) & sync_t2 & (sel_8bit == 1))
// Modified this due to the emulation bug detected
//begin
//rom_addr = {addr_reg[23:3], wr_bytes_2to0} ;
prom_data[63:0] <= #1 {56'b0,dbus_out[7:0]} ;
//end
else
if (( state == START_WRITE_H) & sync_t2 & (sel_8bit == 0))
prom_data[63:0] <= #1 dbus_out[63:0] ;
wire [1:0] prom_p_reply = {((state == READ_DONE_H) |
(state == READ_DONE_BYTE) |
(state == WRITE_DONE_H)),
((state == READ_DONE_BYTE) |
(state == READ_DONE_H))} ;
// Added for timing concern for prom_p_reply
assign prom_read_data = ( (state == READ_DONE_BYTE) | (state == READ_DONE_H) ) ;
reg incr_rom_addr
;
always@(posedge ss_clock)
if ( (sync_t2) & (sel_8bit == 0) )
begin
incr_rom_addr <= #1 ~low_word_only &
((nstate == START_READ_H_BYTE4) |
(nstate == START_WRITE_H) |
(nstate == READ_WAIT_H_BYTE4) |
(nstate == WRITE_WAIT_H)) ;
rom_addr = {addr_reg[23:3], incr_rom_addr, 2'b00} ;
end
// Added deletions for the emulation modification here
else
if (( state == START_WRITE_H) & sync_t2 & (sel_8bit == 1))
rom_addr = {addr_reg[23:3], wr_bytes_2to0} ;
else
if ( ((nstate == START_READ_L_BYTE1) | (nstate == READ_WAIT_L_BYTE1)) & (sync_t2) & (sel_8bit == 1) )
rom_addr = {addr_reg[23:3], 3'b000} ;
else
if ( ((nstate == START_READ_L_BYTE2) | (nstate == READ_WAIT_L_BYTE2)) & (sync_t2) & (sel_8bit == 1) )
rom_addr = {addr_reg[23:3], 3'b001} ;
else
if ( ((nstate == START_READ_L_BYTE3) | (nstate == READ_WAIT_L_BYTE3)) & (sync_t2) & (sel_8bit == 1) )
rom_addr = {addr_reg[23:3], 3'b010} ;
else
if ( ((nstate == START_READ_L_BYTE4) | (nstate == READ_WAIT_L_BYTE4)) & (sync_t2) & (sel_8bit == 1) )
rom_addr = {addr_reg[23:3], 3'b011} ;
else
if ( ((nstate == START_READ_H_BYTE1) | (nstate == READ_WAIT_H_BYTE1)) & (sync_t2) & (sel_8bit == 1) )
rom_addr = {addr_reg[23:3], 3'b100} ;
else
if ( ((nstate == START_READ_H_BYTE2) | (nstate == READ_WAIT_H_BYTE2)) & (sync_t2) & (sel_8bit == 1) )
rom_addr = {addr_reg[23:3], 3'b101} ;
else
if ( ((nstate == START_READ_H_BYTE3) | (nstate == READ_WAIT_H_BYTE3)) & (sync_t2) & (sel_8bit == 1) )
rom_addr = {addr_reg[23:3], 3'b110} ;
else
if ( ((nstate == START_READ_H_BYTE4) | (nstate == READ_WAIT_H_BYTE4)) & (sync_t2) & (sel_8bit == 1) )
rom_addr = {addr_reg[23:3], 3'b111} ;
else
if ( ((nstate == START_READ_BYTE) | (nstate == READ_WAIT_BYTE)) & (sync_t2) & (sel_8bit == 1) )
rom_addr = {addr_reg[23:3], wr_bytes_2to0} ;
reg rom_cs_l ;
always@(posedge ss_clock)
if (ss_reset)
rom_cs_l <= #1 1'b1 ;
else if (sync_t2)
rom_cs_l <= #1 ~( (nstate == READ_WAIT_L_BYTE1) |
(nstate == READ_WAIT_L_BYTE2) |
(nstate == READ_WAIT_L_BYTE3) |
(nstate == READ_WAIT_L_BYTE4) |
(nstate == READ_WAIT_H_BYTE1) |
(nstate == READ_WAIT_H_BYTE2) |
(nstate == READ_WAIT_H_BYTE3) |
(nstate == READ_WAIT_H_BYTE4) |
(nstate == READ_WAIT_BYTE) |
(nstate == WRITE_WAIT_L) |
(nstate == WRITE_WAIT_H)) ;
reg rom_oe_l ;
always@(posedge ss_clock)
if (ss_reset)
rom_oe_l <= #1 1'b1 ;
else if (sync_t2)
rom_oe_l <= #1 ~( (nstate == START_READ_L_BYTE1) |
(nstate == START_READ_L_BYTE2) |
(nstate == START_READ_L_BYTE3) |
(nstate == START_READ_L_BYTE4) |
(nstate == START_READ_BYTE) |
(nstate == READ_WAIT_L_BYTE1) |
(nstate == READ_WAIT_L_BYTE2) |
(nstate == READ_WAIT_L_BYTE3) |
(nstate == READ_WAIT_L_BYTE4) |
(nstate == READ_WAIT_BYTE) |
(nstate == START_READ_H_BYTE1) |
(nstate == START_READ_H_BYTE2) |
(nstate == START_READ_H_BYTE3) |
(nstate == START_READ_H_BYTE4) |
(nstate == READ_WAIT_H_BYTE1) |
(nstate == READ_WAIT_H_BYTE2) |
(nstate == READ_WAIT_H_BYTE3) |
(nstate == READ_WAIT_H_BYTE4) ) ;
reg rom_we_l ;
always@(posedge ss_clock)
if (ss_reset)
rom_we_l <= #1 1'b1 ;
else if (sync_t2)
rom_we_l <= #1 ~((counter != 'b1) & (counter != 'b0) &
((state == WRITE_WAIT_L) |
(state == WRITE_WAIT_H))) ;
endmodule
This page: |
Created: | Thu Aug 19 12:02:11 1999 |
| From: |
../../../sparc_v8/ssparc/promif/rtl/promif.v
|