目次

DualPortMemory

 最近の市販FPGAには、大抵メモリが積まれています。  内蔵メモリは、Singleポートのメモリではなく  Dualポート型が採用されています。  DulaPortMemoryは、2つのポートを持ち、次の  ような使い方ができるようになっています。  (2つのポートをA、Bとします。)  上の組合せには、ビット幅を含めていませんが  2つのポートで、入出力できるデータビット幅  を変えることもできます。  Singleポートのメモリで、上の組合せを実現  するため、論理回路を用意するのは無駄です  から、FPGAのVendorはDualポートタイプを  内蔵することを選びました。  片側を入出力ポート、もう片側を出力ポートと  する方式は、CPUと入出力ポートを接続し、出力  専用ポートの先にディスプレイを用意する等の  システムを構築する設計者に大いに受入れられ  ます。  バスインタフェースとディスプレイの同期処理  を考えずにシステムを構築できるので、高解像  のディスプレイや圧縮、伸張処理が必要になる  地上デジタルTV等には、必須のメモリです。  地上デジタルTVに代表される、圧縮、伸張を含む  回路とDualポートメモリを1チップ内に収容する  ことが要求されるシステムには、最適なデバイス  として、FPGAは採用されます。  FPGAのVendorにより、DualポートメモリのVHDLコード  記述は異なりますが、ライブラリを指定しておけば  コンポーネントとして利用できるようになっています。  ここでは、下図のようにDualポートメモリを扱い  マイクロコンピュータのファームウエアで、リード  とライトさせてみます。  手元にあるSpartan3の200kゲートデバイスの  内部DualPortMemoryをアクセスするため、  BUSインタフェースを入れます。  マイクロコンピュータは、Spartan3が3.3V動作  であることを考慮してAnalogDevicesのADuC7026  を利用します。ADuC7026は、ARMコア内蔵です。  10ピンケーブルを2本使い、ARMとFPGAを接続します。  ARMとPersonalComputerは、シリアルケーブルで  接続します。シリアルインタフェースのコマンド  を決めます。  アドレスは、コマンドとパラメータを指定して  操作します。  シリアルインタフェースの仕様は、次のように  決めておきます。  ARMのファームウエアソースコードは、以下。 #include <ADuC7026.h> #define OFF 0 #define ON OFF+1 /* data definitions */ typedef unsigned char UBYTE ; typedef signed char SBYTE ; typedef unsigned short UWORD ; typedef signed short SWORD ; typedef unsigned long ULONG ; typedef signed long SLONG ; void IRQ_Handler(void) __irq; void init_usr(void); #define MASKFF 0xFF #define MASK0F 0x0F #define MASKF0 0xF0 #define MASK80 0x80 #define MASK40 0x40 #define MASK20 0x20 #define MASK10 0x10 #define MASK08 0x08 #define MASK04 0x04 #define MASK02 0x02 #define MASK01 0x01 ULONG timcnt ; void rs_putchar(UBYTE x); void crlf(void); void rs_puts(UBYTE *x); UBYTE get_hex(UBYTE x); void show_help(void); void delay_100us(UWORD x); void send_atrg(UBYTE x); void send_dtrg(UBYTE x); void send_wtrg(void); void send_rtrg(void); void read_loop(void); void put_value(UBYTE kind,UWORD x); UBYTE get_bport_val(void); /* global variables */ volatile UBYTE uflag ; volatile UBYTE sbuf[8] ; volatile UBYTE sindex ; volatile UBYTE cmd ; volatile UBYTE asc_hex[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; volatile UBYTE oflag ; volatile UBYTE dat ; volatile UWORD adra ; volatile UWORD adrb ; #define ALAST 2048 int main(void) { UBYTE tmp ; /* initialize user */ init_usr(); /* endless loop */ while(ON) { /* opening message */ if ( oflag == ON ) { /* clear flag */ oflag = OFF ; /* show message */ rs_puts("Hello"); crlf(); } /* command interrpreter */ if ( uflag == ON ) { /* clear flag */ uflag = OFF ; /* new line */ crlf(); /* judge */ cmd = *(sbuf+0) ; if ( cmd == '?' ) { show_help(); } /* address */ if ( cmd == 'A' ) { /* get command */ tmp = *(sbuf+1) ; /* send command */ switch ( tmp ) { case '0' : send_atrg(0); adra = 0 ; break ; case '1' : send_atrg(1); adra++ ; break ; case '2' : send_atrg(2); adra-- ; break ; case '4' : send_atrg(4); adrb = 0 ; break ; case '5' : send_atrg(5); adrb++ ; break ; case '6' : send_atrg(6); adrb-- ; break ; default : break ; } } /* data */ if ( cmd == 'D' ) { /* get data */ dat = get_hex( *(sbuf+1) ); dat <<= 4 ; dat |= get_hex( *(sbuf+2) ); /* store data */ send_dtrg(dat); } /* store data from A port */ if ( cmd == 'W' ) { send_wtrg(); } /* read B port data */ if ( cmd == 'R' ) { read_loop(); } /* show values */ if ( cmd == 'S' ) { rs_puts("AddressA = "); put_value(ON, adra ) ; crlf() ; rs_puts("Data = "); put_value(OFF,dat ) ; crlf() ; rs_puts("AddressB = "); put_value(ON ,adrb ) ; crlf() ; } } } /* dummy return */ return (0); } void IRQ_Handler(void) __irq { volatile UBYTE ch ; /* judge UART receive interruption */ if ( (IRQSTA & UART_BIT) == UART_BIT ) { /* judge */ if ( COMSTA0 & 1 ) { /* clear flag */ ch = COMRX ; *(sbuf+sindex) = ch ; sindex++ ; if ( ch == '\r' ) { sindex = 0 ; uflag = ON ; } } } /* judge timer3 interruption (1ms) */ if ( (IRQSTA & WATCHDOG_TIMER_BIT) == WATCHDOG_TIMER_BIT ) { /* clear timer3 interrupt flag */ T3CLRI = 0xff ; /* increment */ timcnt++ ; /* blink */ if ( (timcnt & 0x3ff) == 1000 ) { GP4DAT ^= (1 << 23); } } } void init_usr(void) { /* select clock 10.44MHz initialized in start up routine */ PLLKEY1 = 0xaa ; PLLCON = 0x01 ; PLLKEY2 = 0x55 ; /* power control initialized in start up routine */ /* initialize flag */ uflag = OFF ; oflag = ON ; /* clear counter */ timcnt = 0 ; /* initialize UART */ { /* set baud rate 19200 bps CD = 2 */ COMCON0 = 0x80 ; /* select COMDIV1 and COMDIV0 */ COMDIV0 = 0x11 ; COMDIV1 = 0x00 ; /* set conditions */ COMCON0 = 0x03 ; /* select COMRX and COMTX , 8bit data , 1 stop bit , no parity */ /* enable interrupt */ COMIEN0 = 0x01 ; /* ERBFI */ } /* P0 */ { /* */ GP0DAT = 0xDF000000 ; } /* P1 */ { /* use UART */ GP1CON = 0x00000011 ; /* */ GP1DAT = 0xfef00000 ; } /* P2 */ { /* all bits outputs */ GP2DAT = 0xff000000 ; } /* P3 */ { /* all bits outputs */ GP3DAT = 0xff000000 ; } /* P4 */ { GP4DAT = 0xff000000 ; } /* */ adra = 0 ; dat = 0 ; adrb = 0 ; /* initialize timer 3 (1s) */ { T3LD = 33 ; /* (32.768kHz / 33) = about 1kHz */ T3CON = 0xc0 ; /* enable , cyclic , 1/1 */ } /* enable timer 3 interrupt and UART interrupt */ IRQEN = WATCHDOG_TIMER_BIT | UART_BIT ; } /* UART putchar */ void rs_putchar(UBYTE x) { /* ? transmmit buffer empty */ while( (COMSTA0 & 0x40) == 0 ) ; /* set value */ COMTX = x ; } /* carriage return and line feed */ void crlf(void) { rs_putchar('\r'); rs_putchar('\n'); } /* UART puts */ void rs_puts(UBYTE *x) { while ( *x != '\0' ) { rs_putchar( *x ) ; x++ ; } } /* convert ASCII to number */ UBYTE get_hex(UBYTE x) { UBYTE result ; /* default */ result = 0 ; /* judge */ if ( '0' <= x && x <= '9' ) { result = x - '0' ; } if ( 'A' <= x && x <= 'F' ) { result = x - 'A' + 10 ; } if ( 'a' <= x && x <= 'f' ) { result = x - 'a' + 10 ; } return result ; } /* show help */ void show_help(void) { rs_puts("? help") ; crlf(); rs_puts("A handling address") ; crlf(); rs_puts(" A0 clear A port address") ; crlf(); rs_puts(" A1 increase A port address") ; crlf(); rs_puts(" A2 decrease A port address") ; crlf(); rs_puts(" A4 clear B port address") ; crlf(); rs_puts(" A5 increase B port address") ; crlf(); rs_puts(" A6 decrease B port address") ; crlf(); rs_puts("D set data") ; crlf(); rs_puts("W write value to A port ") ; crlf(); rs_puts("R read B port data") ; crlf(); rs_puts("S show values") ; crlf(); } void delay_100us(UWORD x) { ULONG last ; /* calculate */ last = timcnt + x ; /* wait */ while ( timcnt < last ) ; } #define ATRG_BIT 1 #define DTRG_BIT 2 #define WTRG_BIT 4 #define RTRG_BIT 8 #define SFT_SIZE 16 void send_atrg(UBYTE x) { /* clear */ GP2DAT &= ~(ATRG_BIT << SFT_SIZE) ; /* impress */ GP3DAT &= 0xff00ffff ; GP3DAT |= (x << SFT_SIZE); delay_100us(2); /* trigger */ GP2DAT |= (ATRG_BIT << SFT_SIZE); delay_100us(2); GP2DAT &= ~(ATRG_BIT << SFT_SIZE); } void send_dtrg(UBYTE x) { /* clear */ GP2DAT &= ~(DTRG_BIT << SFT_SIZE) ; /* impress */ GP3DAT &= 0xff00ffff ; GP3DAT |= (x << SFT_SIZE); delay_100us(2); /* trigger */ GP2DAT |= (DTRG_BIT << SFT_SIZE); delay_100us(2); GP2DAT &= ~(DTRG_BIT << SFT_SIZE) ; delay_100us(2); } void send_wtrg(void) { /* clear */ GP2DAT &= ~(WTRG_BIT << SFT_SIZE); /* trigger */ GP2DAT |= (WTRG_BIT << SFT_SIZE); delay_100us(2); GP2DAT &= ~(WTRG_BIT << SFT_SIZE); } void send_rtrg(void) { /* clear */ GP2DAT &= ~(RTRG_BIT << SFT_SIZE); /* trigger */ GP2DAT |= (RTRG_BIT << SFT_SIZE); delay_100us(2); GP2DAT &= ~(RTRG_BIT << SFT_SIZE); } void read_loop(void) { UBYTE result ; UBYTE madr[5] ; UWORD i ; /* default */ *(madr+3) = ':'; *(madr+4) = '\0'; /* clear address */ send_atrg(4); /* loop */ for ( i = 0 ; i < ALAST ; i++ ) { /* show address */ if ( (i & MASK0F) == 0 ) { /* calculate address */ *(madr+0) = ((i >> 8) & MASK0F) ; *(madr+1) = ((i >> 4) & MASK0F); *(madr+2) = (i & MASK0F) ; /* convert */ *(madr+0) = asc_hex[*(madr+0)] ; *(madr+1) = asc_hex[*(madr+1)] ; *(madr+2) = asc_hex[*(madr+2)] ; /* show */ rs_puts( madr ); } /* get data */ result = get_bport_val() ; /* show */ put_value(OFF,result); rs_putchar(' '); /* judge new line */ if ( (i & MASK0F) == 15 ) { crlf(); } /* address increment */ send_atrg(5); } } void put_value(UBYTE kind,UWORD x) { UBYTE msg[4] ; /* separate */ *(msg+3) = (x & MASK0F) ; *(msg+2) = (x >> 4) & MASK0F ; if ( kind == ON ) { *(msg+0) = (x >> 12) & MASK0F ; *(msg+1) = (x >> 8) & MASK0F ; /* send charactor */ rs_putchar( asc_hex[*(msg+0)] ) ; rs_putchar( asc_hex[*(msg+1)] ) ; } rs_putchar( asc_hex[*(msg+2)] ) ; rs_putchar( asc_hex[*(msg+3)] ) ; } UBYTE get_bport_val(void) { UBYTE result ; /* set default */ result = 0 ; /* transfer data */ send_rtrg(); /* change P3 as input */ GP3DAT = 0x00000000 ; /* (OE,SEL) = (1,1) */ GP2DAT |= (3 << 20) ; /* delay */ delay_100us(2); /* get data */ result = GP3DAT ; /* (OE,SEL) = (0,0) */ GP2DAT = 0xff000000 ; /* change P3 as output */ GP3DAT = 0xff000000 ; return result ; }  DualPortMemoryを定義するには、次の図を利用して  2つのポートの使い方を考えます。  (A、Bともに8ビットとします。)  FPGA内部は、すべて同期回路で動かさないと  いけないので、メモリはレジスタの塊と見る  と、クロックが必要になります。  A、Bの2ポートは、別々のクロックを利用できます。  クロックを入れない限り、該当ポートは使えません。  クロックを供給して使うか否かは、ENA、ENABを  利用します。  データのリード、ライトは、次のタイミングチャートを  見れば、ADDRA、ADDRB、WEA、WEBの使い方を把握できます。  ライトは、アドレス、データを与えて、WEをHIGHに  します。ただし、WEはCLOCKのエッジトリガーのとき  HIGHでなければ、メモリにデータを格納しません。  リードは、アドレスを与え、CLOCKのエッジで  アドレスが記憶されてから、次CLOCKでデータ  が出力されてきます。  データの入出力に、DIA、DIB、DOA、DOBを利用します。  他にパリティの入出力がありますが、パリティは付加と  いう意味だけで、データのビット組合せにより1、0と  なることはありません。単純に、付加するビットになる  だけです。DIAP、DIBP、DOAP、DOBPがパリティになり  ます。  SSRA、SSRBは、メモリの内容を同期セット、同期リセット  に使います。  ここまでで、信号の意味が理解できたので、Aポートを  ライト専用、Bポートをリード専用で使うとすると、次  のように信号線を割り当てます。  利用しない入力は、論理値を'1'とし  出力はopenで記述します。  DualPortMemoryのコンポーネントのインスタンス  指定記述は、以下。 RAMB16_S9_S9_inst : RAMB16_S9_S9 generic map ( INIT_A => X"000", -- Value of output RAM registers on Port A at startup INIT_B => X"000", -- Value of output RAM registers on Port B at startup SRVAL_A => X"000", -- Port A ouput value upon SSR assertion SRVAL_B => X"000", -- Port B ouput value upon SSR assertion WRITE_MODE_A => "WRITE_FIRST", -- WRITE_FIRST, READ_FIRST or NO_CHANGE WRITE_MODE_B => "WRITE_FIRST", -- WRITE_FIRST, READ_FIRST or NO_CHANGE SIM_COLLISION_CHECK => "ALL", -- "NONE", "WARNING", "GENERATE_X_ONLY", "ALL" -- The following INIT_xx declarations specify the initial contents of the RAM -- Address 0 to 511 INIT_00 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_01 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_02 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_03 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_05 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_07 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_08 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 512 to 1023 INIT_10 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_11 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_12 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_13 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_14 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_15 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_16 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_17 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_18 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1F => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 1024 to 1535 INIT_20 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_21 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_22 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_23 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_24 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_25 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_26 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_27 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_28 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_29 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2F => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 1536 to 2047 INIT_30 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_31 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000", -- The next set of INITP_xx are for the parity bits -- Address 0 to 511 INITP_00 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_01 => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 512 to 1023 INITP_02 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_03 => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 1024 to 1535 INITP_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_05 => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 1536 to 2047 INITP_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_07 => X"0000000000000000000000000000000000000000000000000000000000000000") port map ( DOA => open, -- Port A 8-bit Data Output DOB => iDOB, -- Port B 8-bit Data Output DOPA => open, -- Port A 1-bit Parity Output DOPB => open, -- Port B 1-bit Parity Output ADDRA => iADDRA, -- Port A 11-bit Address Input ADDRB => iADDRB, -- Port B 11-bit Address Input CLKA => iMCLK, -- Port A Clock CLKB => iMCLK, -- Port B Clock DIA => iDIA, -- Port A 8-bit Data Input DIB => X"FF", -- Port B 8-bit Data Input DIPA => "1", -- Port A 1-bit parity Input DIPB => "1", -- Port B 1-bit parity Input ENA => '1', -- Port A RAM Enable Input ENB => '1', -- Port B RAM Enable Input SSRA => '0', -- Port A Synchronous Set/Reset Input SSRB => '0', -- Port B Synchronous Set/Reset Input WEA => iWEA, -- Port A Write Enable Input WEB => '0' -- Port B Write Enable Input );  INIT_A、INIT_Bは、メモリに接続している  出力バッファの非同期リセット時の出力値  を指定します。  SRVAL_A、SRVAL_Bは、同期セット、同期リセット  時のポート出力値を指定します。  WRITE_MODE_A、WRITE_MODE_Bは、2ポートからの  ライトとリードが同時指定された場合、リードと  ライトのどちらを優先させるかを指定します。  2つのポートにリード、ライト用のシーケンサを接続  し、バスインタフェースを入れ、VHDLコードが完成。 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; Library UNISIM; use UNISIM.vcomponents.all; entity dpmtst is generic ( TOPX : integer := 2 ; XMAX : integer := 3 --; ); port ( -- system nRESET : in std_logic ; CLOCK : in std_logic ; -- trigger ATRG : in std_logic ; DTRG : in std_logic ; WTRG : in std_logic ; RTRG : in std_logic ; SEL : in std_logic ; OE : in std_logic ; -- data BUS ADBUS : inout std_logic_vector(7 downto 0) ; -- selector ASEL : in std_logic ; -- address monitor ROUT : out std_logic_vector(7 downto 0) ; GOUT : out std_logic_vector(3 downto 0) --; ); end dpmtst; architecture Behavioral of dpmtst is -- component clock generator component clkgenx is generic ( TOPX : integer ; RMAX : integer --; ); port ( -- system nRESET : in std_logic ; CLOCK : in std_logic ; -- output CLKOUT : out std_logic -- ; ); end component ; -- clock signal iMCLK : std_logic ; -- trigger signal iATRG_SFT : std_logic_vector(2 downto 0) ; signal iDTRG_SFT : std_logic_vector(2 downto 0) ; signal iWTRG_SFT : std_logic_vector(2 downto 0) ; signal iRTRG_SFT : std_logic_vector(2 downto 0) ; signal iATRG : std_logic ; signal iDTRG : std_logic ; signal iWTRG : std_logic ; signal iRTRG : std_logic ; -- internal registers signal iMAR : std_logic_vector(2 downto 0) ; signal iMDR : std_logic_vector(7 downto 0) ; signal iMARA : std_logic_vector(10 downto 0) ; signal iMARB : std_logic_vector(10 downto 0) ; signal iADBUS : std_logic_vector(7 downto 0) ; signal iMSTATE : std_logic_vector(1 downto 0) ; -- internal registers (A port) signal iASTATE : std_logic_vector(1 downto 0) ; signal iADDRA : std_logic_vector(10 downto 0) ; signal iDIA : std_logic_vector(7 downto 0) ; signal iWEA : std_logic ; -- internal registers (Bport) signal iBSTATE : std_logic_vector(1 downto 0) ; signal iDOB : std_logic_vector(7 downto 0) ; signal iADDRB : std_logic_vector(10 downto 0) ; signal iBDAT : std_logic_vector(7 downto 0) ; begin -- component clock generator (48MHz/6 = 8MHz) CLKX : clkgenx generic map (TOPX,XMAX) port map (nRESET,CLOCK,iMCLK); RAMB16_S9_S9_inst : RAMB16_S9_S9 generic map ( INIT_A => X"000", -- Value of output RAM registers on Port A at startup INIT_B => X"000", -- Value of output RAM registers on Port B at startup SRVAL_A => X"000", -- Port A ouput value upon SSR assertion SRVAL_B => X"000", -- Port B ouput value upon SSR assertion WRITE_MODE_A => "WRITE_FIRST", -- WRITE_FIRST, READ_FIRST or NO_CHANGE WRITE_MODE_B => "WRITE_FIRST", -- WRITE_FIRST, READ_FIRST or NO_CHANGE SIM_COLLISION_CHECK => "ALL", -- "NONE", "WARNING", "GENERATE_X_ONLY", "ALL" -- The following INIT_xx declarations specify the initial contents of the RAM -- Address 0 to 511 INIT_00 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_01 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_02 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_03 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_05 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_07 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_08 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 512 to 1023 INIT_10 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_11 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_12 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_13 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_14 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_15 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_16 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_17 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_18 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1F => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 1024 to 1535 INIT_20 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_21 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_22 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_23 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_24 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_25 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_26 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_27 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_28 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_29 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2F => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 1536 to 2047 INIT_30 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_31 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000", -- The next set of INITP_xx are for the parity bits -- Address 0 to 511 INITP_00 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_01 => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 512 to 1023 INITP_02 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_03 => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 1024 to 1535 INITP_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_05 => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 1536 to 2047 INITP_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_07 => X"0000000000000000000000000000000000000000000000000000000000000000") port map ( DOA => open, -- Port A 8-bit Data Output DOB => iDOB, -- Port B 8-bit Data Output DOPA => open, -- Port A 1-bit Parity Output DOPB => open, -- Port B 1-bit Parity Output ADDRA => iADDRA, -- Port A 11-bit Address Input ADDRB => iADDRB, -- Port B 11-bit Address Input CLKA => iMCLK, -- Port A Clock CLKB => iMCLK, -- Port B Clock DIA => iDIA, -- Port A 8-bit Data Input DIB => X"FF", -- Port B 8-bit Data Input DIPA => "1", -- Port A 1-bit parity Input DIPB => "1", -- Port B 1-bit parity Input ENA => '1', -- Port A RAM Enable Input ENB => '1', -- Port B RAM Enable Input SSRA => '0', -- Port A Synchronous Set/Reset Input SSRB => '0', -- Port B Synchronous Set/Reset Input WEA => iWEA, -- Port A Write Enable Input WEB => '0' -- Port B Write Enable Input ); -- monitor output ROUT <= (not iMARB(7 downto 0)) when ( ASEL = '1' ) else (not iMARA(7 downto 0)) ; GOUT <= ('1' & (not iMARB(10 downto 8))) when ( ASEL = '1' ) else ('1' & (not iMARA(10 downto 8))) ; -- monitor iADBUS <= iBDAT when ( SEL = '1' ) else iMDR ; -- output ADBUS <= iADBUS when ( OE = '1' ) else (others => 'Z'); -- trigger process (nRESET,iMCLK) begin if ( nRESET = '0' ) then iATRG_SFT <= "000" ; iDTRG_SFT <= "000" ; iWTRG_SFT <= "000" ; iRTRG_SFT <= "000" ; elsif rising_edge(iMCLK) then iATRG_SFT <= iATRG_SFT(1 downto 0) & ATRG ; iDTRG_SFT <= iDTRG_SFT(1 downto 0) & DTRG ; iWTRG_SFT <= iWTRG_SFT(1 downto 0) & WTRG ; iRTRG_SFT <= iRTRG_SFT(1 downto 0) & RTRG ; end if ; end process ; iATRG <= '1' when ( iATRG_SFT = "011" or iATRG_SFT = "001" ) else '0' ; iDTRG <= '1' when ( iDTRG_SFT = "011" or iDTRG_SFT = "001" ) else '0' ; iWTRG <= '1' when ( iWTRG_SFT = "011" or iWTRG_SFT = "001" ) else '0' ; iRTRG <= '1' when ( iRTRG_SFT = "011" or iRTRG_SFT = "001" ) else '0' ; -- BUS interface process (nRESET,iMCLK) begin if ( nRESET = '0' ) then iMAR <= "111" ; iMDR <= (others => '0') ; elsif rising_edge( iMCLK ) then if ( iATRG = '1' ) then iMAR <= ADBUS(2 downto 0) ; end if ; if ( iDTRG = '1' ) then iMDR <= ADBUS ; end if ; end if ; end process ; -- address handling process (nRESET,iMCLK) begin if ( nRESET = '0' ) then iMAR <= "111" ; iMDR <= (others => '0') ; iMARA <= (others => '0') ; iMARB <= (others => '0') ; iMSTATE <= "00" ; elsif rising_edge( iMCLK ) then case conv_integer(iMSTATE) is -- wait trigger when 0 => if ( iATRG = '1' ) then iMSTATE <= "01" ; iMAR <= ADBUS(2 downto 0) ; elsif ( iDTRG = '1' ) then iMSTATE <= "10" ; iMDR <= ADBUS ; else iMSTATE <= "00" ; end if ; -- handling when 1 => iMSTATE <= "11" ; -- clear A port ADDRESS if ( iMAR = "000" ) then iMARA <= (others => '0') ; end if ; -- increase A port ADDRESS if ( iMAR = "001" ) then iMARA <= iMARA + '1' ; end if ; -- decrease A port ADDRESS if ( iMAR = "010" ) then iMARA <= iMARA - '1' ; end if ; -- clear B port ADDRESS if ( iMAR = "100" ) then iMARB <= (others => '0') ; end if ; -- increase B port ADDRESS if ( iMAR = "101" ) then iMARB <= iMARB + '1' ; end if ; -- decrease B port ADDRESS if ( iMAR = "110" ) then iMARB <= iMARB - '1' ; end if ; -- skip when 3 => iMSTATE <= "10" ; -- return first state when 2 => iMSTATE <= "00" ; -- default when others => iMSTATE <= "00" ; end case ; end if ; end process ; -- sequencer (A port) process (nRESET,iMCLK) begin if ( nRESET = '0' ) then iASTATE <= "00" ; iADDRA <= (others => '0') ; elsif rising_edge( iMCLK ) then case conv_integer(iASTATE) is -- wait trigger when 0 => if ( iWTRG = '1' ) then iASTATE <= "01" ; else iASTATE <= "00" ; end if ; -- transfer when 1 => iASTATE <= "11" ; iADDRA <= iMARA ; iDIA <= iMDR ; -- enable when 3 => iASTATE <= "10" ; -- return first state when 2 => iASTATE <= "00" ; -- default when others => iASTATE <= "00" ; end case ; end if ; end process ; iWEA <= '1' when ( iASTATE = "11" ) else '0' ; -- sequencer (B port) process (nRESET,iMCLK) begin if ( nRESET = '0' ) then iBSTATE <= "00" ; iADDRB <= (others => '0') ; iBDAT <= (others => '0') ; elsif rising_edge( iMCLK ) then case conv_integer(iBSTATE) is -- wait trigger when 0 => if ( iRTRG = '1' ) then iBSTATE <= "01" ; iADDRB <= iMARB ; else iBSTATE <= "00" ; end if ; -- confirm address when 1 => iBSTATE <= "11" ; -- get data when 3 => iBSTATE <= "10" ; iBDAT <= iDOB ; -- return first state when 2 => iBSTATE <= "00" ; -- default when others => iBSTATE <= "00" ; end case ; end if ; end process ; end Behavioral;  ライト、リードのシーケンサは、ハザード  が発生しないように、ジョンソンカウンタ  を利用します。  2つのポートのアドレス更新を目視できる  ように、外部にLEDとスイッチを接続できる  ようにしてあります。  ピンアサインは、以下。 # system NET "CLOCK" LOC = "P55" | IOSTANDARD = LVCMOS33 ; NET "nRESET" LOC = "P73" | IOSTANDARD = LVCMOS33 ; # G0 NET "ADBUS<0>" LOC = "P1" | IOSTANDARD = LVCMOS33 ; NET "ADBUS<1>" LOC = "P2" | IOSTANDARD = LVCMOS33 ; NET "ADBUS<2>" LOC = "P4" | IOSTANDARD = LVCMOS33 ; NET "ADBUS<3>" LOC = "P5" | IOSTANDARD = LVCMOS33 ; NET "ADBUS<4>" LOC = "P6" | IOSTANDARD = LVCMOS33 ; NET "ADBUS<5>" LOC = "P7" | IOSTANDARD = LVCMOS33 ; NET "ADBUS<6>" LOC = "P8" | IOSTANDARD = LVCMOS33 ; NET "ADBUS<7>" LOC = "P10" | IOSTANDARD = LVCMOS33 ; # G1 NET "ATRG" LOC = "P11" | IOSTANDARD = LVCMOS33 ; NET "DTRG" LOC = "P12" | IOSTANDARD = LVCMOS33 ; NET "WTRG" LOC = "P13" | IOSTANDARD = LVCMOS33 ; NET "RTRG" LOC = "P14" | IOSTANDARD = LVCMOS33 ; NET "SEL" LOC = "P15" | IOSTANDARD = LVCMOS33 ; NET "OE" LOC = "P17" | IOSTANDARD = LVCMOS33 ; # G0B NET "ROUT<0>" LOC = "P141" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "ROUT<1>" LOC = "P140" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "ROUT<2>" LOC = "P137" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "ROUT<3>" LOC = "P135" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "ROUT<4>" LOC = "P132" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "ROUT<5>" LOC = "P131" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "ROUT<6>" LOC = "P130" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "ROUT<7>" LOC = "P129" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; # G1B NET "GOUT<0>" LOC = "P116" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "GOUT<1>" LOC = "P113" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "GOUT<2>" LOC = "P119" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "GOUT<3>" LOC = "P118" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "ASEL" LOC = "P123" | IOSTANDARD = LVCMOS33 ;  端末ソフトを利用して、動作確認しました。  Aポートからデータを入力し、Bポートから  読出して、一致することを確認できます。  アドレス表示に利用したLED、LED+スイッチの  基板は、以下です。  アドレス11ビット中、8ビットをLED基板で表示し  残りはLED+スイッチ基板に任せています。  スイッチでA、Bポートのアドレスを切り替えて  表示します。  1つのDualPortMemoryの入出力操作を確認した  ので、4つカスケードに接続して、動かします。  2kバイトのDualPortMemoryの各アドレスとライト側  データとリード側データの2レジスタを用意します。  アドレスは13ビット必要ですが、各々のDualPortMemory  のアドレス11ビットを用意し、リード、ライトが必要な  ときに、転送して使います。  バスインタフェースに細工をし、次のようにコマンドで  2つのポートアドレスを操作します。  A port側から入力するデータは、8ビットで  渡します。  B port側から出力するデータは、セレクタを  利用して、バッファに保存後、出力します。  これらの内容を追加して、VHDLコードを定義  し直しました。 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; Library UNISIM; use UNISIM.vcomponents.all; entity dpmtstx is generic ( TOPX : integer := 2 ; XMAX : integer := 3 --; ); port ( -- system nRESET : in std_logic ; CLOCK : in std_logic ; -- trigger ATRG : in std_logic ; DTRG : in std_logic ; WTRG : in std_logic ; RTRG : in std_logic ; SEL : in std_logic ; OE : in std_logic ; -- selector ASEL : in std_logic ; -- data BUS ADBUS : inout std_logic_vector(7 downto 0) ; -- address monitor ROUT : out std_logic_vector(7 downto 0) ; GOUT : out std_logic_vector(4 downto 0) --; ); end dpmtstx; architecture Behavioral of dpmtstx is -- component clock generator component clkgenx is generic ( TOPX : integer ; RMAX : integer --; ); port ( -- system nRESET : in std_logic ; CLOCK : in std_logic ; -- output CLKOUT : out std_logic -- ; ); end component ; -- clock signal iMCLK : std_logic ; -- trigger signal iATRG_SFT : std_logic_vector(2 downto 0) ; signal iDTRG_SFT : std_logic_vector(2 downto 0) ; signal iWTRG_SFT : std_logic_vector(2 downto 0) ; signal iRTRG_SFT : std_logic_vector(2 downto 0) ; signal iATRG : std_logic ; signal iDTRG : std_logic ; signal iWTRG : std_logic ; signal iRTRG : std_logic ; -- internal registers signal iMAR : std_logic_vector(2 downto 0) ; signal iMDR : std_logic_vector(7 downto 0) ; signal iADBUS : std_logic_vector(7 downto 0) ; signal iMSTATE : std_logic_vector(1 downto 0) ; -- internal registers (A port) signal iASTATE : std_logic_vector(1 downto 0) ; signal iADDRA : std_logic_vector(12 downto 0); signal iADRA_A : std_logic_vector(10 downto 0); signal iADRA_B : std_logic_vector(10 downto 0); signal iADRA_C : std_logic_vector(10 downto 0); signal iADRA_D : std_logic_vector(10 downto 0); signal iDIA : std_logic_vector(7 downto 0) ; signal iWEA : std_logic ; signal iWE_A : std_logic ; signal iWE_B : std_logic ; signal iWE_C : std_logic ; signal iWE_D : std_logic ; -- internal registers (Bport) signal iBSTATE : std_logic_vector(1 downto 0) ; signal iDOB : std_logic_vector(7 downto 0) ; signal iDOB_A : std_logic_vector(7 downto 0) ; signal iDOB_B : std_logic_vector(7 downto 0) ; signal iDOB_C : std_logic_vector(7 downto 0) ; signal iDOB_D : std_logic_vector(7 downto 0) ; signal iADDRB : std_logic_vector(12 downto 0); signal iADRB_A : std_logic_vector(10 downto 0); signal iADRB_B : std_logic_vector(10 downto 0); signal iADRB_C : std_logic_vector(10 downto 0); signal iADRB_D : std_logic_vector(10 downto 0); begin -- component clock generator (48MHz/6 = 8MHz) CLKX : clkgenx generic map (TOPX,XMAX) port map (nRESET,CLOCK,iMCLK); RAMB16_S9_S9_instA : RAMB16_S9_S9 generic map ( INIT_A => X"000", -- Value of output RAM registers on Port A at startup INIT_B => X"000", -- Value of output RAM registers on Port B at startup SRVAL_A => X"000", -- Port A ouput value upon SSR assertion SRVAL_B => X"000", -- Port B ouput value upon SSR assertion WRITE_MODE_A => "WRITE_FIRST", -- WRITE_FIRST, READ_FIRST or NO_CHANGE WRITE_MODE_B => "WRITE_FIRST", -- WRITE_FIRST, READ_FIRST or NO_CHANGE SIM_COLLISION_CHECK => "ALL", -- "NONE", "WARNING", "GENERATE_X_ONLY", "ALL" -- The following INIT_xx declarations specify the initial contents of the RAM -- Address 0 to 511 INIT_00 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_01 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_02 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_03 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_05 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_07 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_08 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 512 to 1023 INIT_10 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_11 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_12 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_13 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_14 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_15 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_16 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_17 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_18 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1F => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 1024 to 1535 INIT_20 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_21 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_22 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_23 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_24 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_25 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_26 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_27 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_28 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_29 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2F => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 1536 to 2047 INIT_30 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_31 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000", -- The next set of INITP_xx are for the parity bits -- Address 0 to 511 INITP_00 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_01 => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 512 to 1023 INITP_02 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_03 => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 1024 to 1535 INITP_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_05 => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 1536 to 2047 INITP_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_07 => X"0000000000000000000000000000000000000000000000000000000000000000") port map ( DOA => open, -- Port A 8-bit Data Output DOB => iDOB_A, -- Port B 8-bit Data Output DOPA => open, -- Port A 1-bit Parity Output DOPB => open, -- Port B 1-bit Parity Output ADDRA => iADRA_A, -- Port A 11-bit Address Input ADDRB => iADRB_A, -- Port B 11-bit Address Input CLKA => iMCLK, -- Port A Clock CLKB => iMCLK, -- Port B Clock DIA => iDIA, -- Port A 8-bit Data Input DIB => X"FF", -- Port B 8-bit Data Input DIPA => "1", -- Port A 1-bit parity Input DIPB => "1", -- Port B 1-bit parity Input ENA => '1', -- Port A RAM Enable Input ENB => '1', -- Port B RAM Enable Input SSRA => '0', -- Port A Synchronous Set/Reset Input SSRB => '0', -- Port B Synchronous Set/Reset Input WEA => iWE_A, -- Port A Write Enable Input WEB => '0' -- Port B Write Enable Input ); RAMB16_S9_S9_instB : RAMB16_S9_S9 generic map ( INIT_A => X"000", -- Value of output RAM registers on Port A at startup INIT_B => X"000", -- Value of output RAM registers on Port B at startup SRVAL_A => X"000", -- Port A ouput value upon SSR assertion SRVAL_B => X"000", -- Port B ouput value upon SSR assertion WRITE_MODE_A => "WRITE_FIRST", -- WRITE_FIRST, READ_FIRST or NO_CHANGE WRITE_MODE_B => "WRITE_FIRST", -- WRITE_FIRST, READ_FIRST or NO_CHANGE SIM_COLLISION_CHECK => "ALL", -- "NONE", "WARNING", "GENERATE_X_ONLY", "ALL" -- The following INIT_xx declarations specify the initial contents of the RAM -- Address 0 to 511 INIT_00 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_01 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_02 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_03 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_05 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_07 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_08 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 512 to 1023 INIT_10 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_11 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_12 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_13 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_14 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_15 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_16 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_17 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_18 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1F => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 1024 to 1535 INIT_20 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_21 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_22 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_23 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_24 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_25 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_26 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_27 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_28 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_29 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2F => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 1536 to 2047 INIT_30 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_31 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000", -- The next set of INITP_xx are for the parity bits -- Address 0 to 511 INITP_00 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_01 => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 512 to 1023 INITP_02 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_03 => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 1024 to 1535 INITP_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_05 => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 1536 to 2047 INITP_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_07 => X"0000000000000000000000000000000000000000000000000000000000000000") port map ( DOA => open, -- Port A 8-bit Data Output DOB => iDOB_B, -- Port B 8-bit Data Output DOPA => open, -- Port A 1-bit Parity Output DOPB => open, -- Port B 1-bit Parity Output ADDRA => iADRA_B, -- Port A 11-bit Address Input ADDRB => iADRB_B, -- Port B 11-bit Address Input CLKA => iMCLK, -- Port A Clock CLKB => iMCLK, -- Port B Clock DIA => iDIA, -- Port A 8-bit Data Input DIB => X"FF", -- Port B 8-bit Data Input DIPA => "1", -- Port A 1-bit parity Input DIPB => "1", -- Port B 1-bit parity Input ENA => '1', -- Port A RAM Enable Input ENB => '1', -- Port B RAM Enable Input SSRA => '0', -- Port A Synchronous Set/Reset Input SSRB => '0', -- Port B Synchronous Set/Reset Input WEA => iWE_B, -- Port A Write Enable Input WEB => '0' -- Port B Write Enable Input ); RAMB16_S9_S9_instC : RAMB16_S9_S9 generic map ( INIT_A => X"000", -- Value of output RAM registers on Port A at startup INIT_B => X"000", -- Value of output RAM registers on Port B at startup SRVAL_A => X"000", -- Port A ouput value upon SSR assertion SRVAL_B => X"000", -- Port B ouput value upon SSR assertion WRITE_MODE_A => "WRITE_FIRST", -- WRITE_FIRST, READ_FIRST or NO_CHANGE WRITE_MODE_B => "WRITE_FIRST", -- WRITE_FIRST, READ_FIRST or NO_CHANGE SIM_COLLISION_CHECK => "ALL", -- "NONE", "WARNING", "GENERATE_X_ONLY", "ALL" -- The following INIT_xx declarations specify the initial contents of the RAM -- Address 0 to 511 INIT_00 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_01 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_02 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_03 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_05 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_07 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_08 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 512 to 1023 INIT_10 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_11 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_12 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_13 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_14 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_15 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_16 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_17 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_18 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1F => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 1024 to 1535 INIT_20 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_21 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_22 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_23 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_24 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_25 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_26 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_27 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_28 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_29 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2F => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 1536 to 2047 INIT_30 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_31 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000", -- The next set of INITP_xx are for the parity bits -- Address 0 to 511 INITP_00 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_01 => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 512 to 1023 INITP_02 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_03 => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 1024 to 1535 INITP_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_05 => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 1536 to 2047 INITP_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_07 => X"0000000000000000000000000000000000000000000000000000000000000000") port map ( DOA => open, -- Port A 8-bit Data Output DOB => iDOB_C, -- Port B 8-bit Data Output DOPA => open, -- Port A 1-bit Parity Output DOPB => open, -- Port B 1-bit Parity Output ADDRA => iADRA_C, -- Port A 11-bit Address Input ADDRB => iADRB_C, -- Port B 11-bit Address Input CLKA => iMCLK, -- Port A Clock CLKB => iMCLK, -- Port B Clock DIA => iDIA, -- Port A 8-bit Data Input DIB => X"FF", -- Port B 8-bit Data Input DIPA => "1", -- Port A 1-bit parity Input DIPB => "1", -- Port B 1-bit parity Input ENA => '1', -- Port A RAM Enable Input ENB => '1', -- Port B RAM Enable Input SSRA => '0', -- Port A Synchronous Set/Reset Input SSRB => '0', -- Port B Synchronous Set/Reset Input WEA => iWE_C, -- Port A Write Enable Input WEB => '0' -- Port B Write Enable Input ); RAMB16_S9_S9_instD : RAMB16_S9_S9 generic map ( INIT_A => X"000", -- Value of output RAM registers on Port A at startup INIT_B => X"000", -- Value of output RAM registers on Port B at startup SRVAL_A => X"000", -- Port A ouput value upon SSR assertion SRVAL_B => X"000", -- Port B ouput value upon SSR assertion WRITE_MODE_A => "WRITE_FIRST", -- WRITE_FIRST, READ_FIRST or NO_CHANGE WRITE_MODE_B => "WRITE_FIRST", -- WRITE_FIRST, READ_FIRST or NO_CHANGE SIM_COLLISION_CHECK => "ALL", -- "NONE", "WARNING", "GENERATE_X_ONLY", "ALL" -- The following INIT_xx declarations specify the initial contents of the RAM -- Address 0 to 511 INIT_00 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_01 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_02 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_03 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_05 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_07 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_08 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 512 to 1023 INIT_10 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_11 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_12 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_13 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_14 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_15 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_16 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_17 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_18 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1F => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 1024 to 1535 INIT_20 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_21 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_22 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_23 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_24 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_25 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_26 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_27 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_28 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_29 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2F => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 1536 to 2047 INIT_30 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_31 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000", -- The next set of INITP_xx are for the parity bits -- Address 0 to 511 INITP_00 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_01 => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 512 to 1023 INITP_02 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_03 => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 1024 to 1535 INITP_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_05 => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 1536 to 2047 INITP_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_07 => X"0000000000000000000000000000000000000000000000000000000000000000") port map ( DOA => open, -- Port A 8-bit Data Output DOB => iDOB_D, -- Port B 8-bit Data Output DOPA => open, -- Port A 1-bit Parity Output DOPB => open, -- Port B 1-bit Parity Output ADDRA => iADRA_D, -- Port A 11-bit Address Input ADDRB => iADRB_D, -- Port B 11-bit Address Input CLKA => iMCLK, -- Port A Clock CLKB => iMCLK, -- Port B Clock DIA => iDIA, -- Port A 8-bit Data Input DIB => X"FF", -- Port B 8-bit Data Input DIPA => "1", -- Port A 1-bit parity Input DIPB => "1", -- Port B 1-bit parity Input ENA => '1', -- Port A RAM Enable Input ENB => '1', -- Port B RAM Enable Input SSRA => '0', -- Port A Synchronous Set/Reset Input SSRB => '0', -- Port B Synchronous Set/Reset Input WEA => iWE_D, -- Port A Write Enable Input WEB => '0' -- Port B Write Enable Input ); -- monitor output ROUT <= (not iADDRB(7 downto 0)) when ( ASEL = '1' ) else (not iADDRA(7 downto 0)) ; GOUT <= (not iADDRB(12 downto 8)) when ( ASEL = '1' ) else (not iADDRA(12 downto 8)) ; -- monitor iADBUS <= iDOB when ( SEL = '1' ) else iMDR ; -- output ADBUS <= iADBUS when ( OE = '1' ) else (others => 'Z'); -- trigger process (nRESET,iMCLK) begin if ( nRESET = '0' ) then iATRG_SFT <= "000" ; iDTRG_SFT <= "000" ; iWTRG_SFT <= "000" ; iRTRG_SFT <= "000" ; elsif rising_edge(iMCLK) then iATRG_SFT <= iATRG_SFT(1 downto 0) & ATRG ; iDTRG_SFT <= iDTRG_SFT(1 downto 0) & DTRG ; iWTRG_SFT <= iWTRG_SFT(1 downto 0) & WTRG ; iRTRG_SFT <= iRTRG_SFT(1 downto 0) & RTRG ; end if ; end process ; iATRG <= '1' when ( iATRG_SFT = "011" or iATRG_SFT = "001" ) else '0' ; iDTRG <= '1' when ( iDTRG_SFT = "011" or iDTRG_SFT = "001" ) else '0' ; iWTRG <= '1' when ( iWTRG_SFT = "011" or iWTRG_SFT = "001" ) else '0' ; iRTRG <= '1' when ( iRTRG_SFT = "011" or iRTRG_SFT = "001" ) else '0' ; -- BUS interface -- address handler process (nRESET,iMCLK) begin if ( nRESET = '0' ) then iMAR <= "111" ; iMDR <= (others => '0') ; iADDRA <= (others => '0') ; iADDRB <= (others => '0') ; iMSTATE <= "00" ; elsif rising_edge( iMCLK ) then case conv_integer(iMSTATE) is -- wait trigger when 0 => if ( iATRG = '1' ) then iMSTATE <= "01" ; iMAR <= ADBUS(2 downto 0) ; elsif ( iDTRG = '1' ) then iMSTATE <= "10" ; iMDR <= ADBUS ; else iMSTATE <= "00" ; end if ; -- handling when 1 => iMSTATE <= "11" ; -- clear A port ADDRESS if ( iMAR = "000" ) then iADDRA <= (others => '0') ; end if ; -- increase A port ADDRESS if ( iMAR = "001" ) then iADDRA <= iADDRA + '1' ; end if ; -- decrease A port ADDRESS if ( iMAR = "010" ) then iADDRA <= iADDRA - '1' ; end if ; -- increase A port ADDRESS with 2048 displacement if ( iMAR = "011" ) then iADDRA <= iADDRA + X"800" ; end if ; -- clear B port ADDRESS if ( iMAR = "100" ) then iADDRB <= (others => '0') ; end if ; -- increase B port ADDRESS if ( iMAR = "101" ) then iADDRB <= iADDRB + '1' ; end if ; -- decrease B port ADDRESS if ( iMAR = "110" ) then iADDRB <= iADDRB - '1' ; end if ; -- increase B port ADDRESS with 2048 displacement if ( iMAR = "111" ) then iADDRB <= iADDRB + X"800" ; end if ; -- copy when 3 => iMSTATE <= "10" ; -- copy A port ADDRESS (area A) if ( iADDRA(12 downto 11) = "00" ) then iADRA_A <= iADDRA(10 downto 0) ; end if ; -- copy A port ADDRESS (area B) if ( iADDRA(12 downto 11) = "01" ) then iADRA_B <= iADDRA(10 downto 0) ; end if ; -- copy A port ADDRESS (area C) if ( iADDRA(12 downto 11) = "10" ) then iADRA_C <= iADDRA(10 downto 0) ; end if ; -- copy A port ADDRESS (area D) if ( iADDRA(12 downto 11) = "11" ) then iADRA_D <= iADDRA(10 downto 0) ; end if ; -- copy B port ADDRESS (area A) if ( iADDRB(12 downto 11) = "00" ) then iADRB_A <= iADDRB(10 downto 0) ; end if ; -- copy B port ADDRESS (area B) if ( iADDRB(12 downto 11) = "01" ) then iADRB_B <= iADDRB(10 downto 0) ; end if ; -- copy B port ADDRESS (area C) if ( iADDRB(12 downto 11) = "10" ) then iADRB_C <= iADDRB(10 downto 0) ; end if ; -- copy B port ADDRESS (area D) if ( iADDRB(12 downto 11) = "11" ) then iADRB_D <= iADDRB(10 downto 0) ; end if ; -- return first state when 2 => iMSTATE <= "00" ; -- default when others => iMSTATE <= "00" ; end case ; end if ; end process ; -- sequencer (A port) process (nRESET,iMCLK) begin if ( nRESET = '0' ) then iASTATE <= "00" ; elsif rising_edge( iMCLK ) then case conv_integer(iASTATE) is -- wait trigger when 0 => if ( iWTRG = '1' ) then iASTATE <= "01" ; else iASTATE <= "00" ; end if ; -- transfer when 1 => iASTATE <= "11" ; iDIA <= iMDR ; -- enable when 3 => iASTATE <= "10" ; -- return first state when 2 => iASTATE <= "00" ; -- default when others => iASTATE <= "00" ; end case ; end if ; end process ; iWEA <= '1' when ( iASTATE = "11" ) else '0' ; iWE_A <= iWEA when ( iADDRA(12 downto 11) = "00" ) else '0' ; iWE_B <= iWEA when ( iADDRA(12 downto 11) = "01" ) else '0' ; iWE_C <= iWEA when ( iADDRA(12 downto 11) = "10" ) else '0' ; iWE_D <= iWEA when ( iADDRA(12 downto 11) = "11" ) else '0' ; -- sequencer (B port) process (nRESET,iMCLK) begin if ( nRESET = '0' ) then iBSTATE <= "00" ; iDOB <= (others => '0') ; elsif rising_edge( iMCLK ) then case conv_integer(iBSTATE) is -- wait trigger when 0 => if ( iRTRG = '1' ) then iBSTATE <= "01" ; else iBSTATE <= "00" ; end if ; -- confirm address when 1 => iBSTATE <= "11" ; -- get data when 3 => iBSTATE <= "10" ; -- area A if ( iADDRB(12 downto 11) = "00" ) then iDOB <= iDOB_A ; end if ; -- area B if ( iADDRB(12 downto 11) = "01" ) then iDOB <= iDOB_B ; end if ; -- area C if ( iADDRB(12 downto 11) = "10" ) then iDOB <= iDOB_C ; end if ; -- area D if ( iADDRB(12 downto 11) = "11" ) then iDOB <= iDOB_D ; end if ; -- return first state when 2 => iBSTATE <= "00" ; -- default when others => iBSTATE <= "00" ; end case ; end if ; end process ; end Behavioral;  マイクロコンピュータと接続し、動作確認するため  ピンアサインをUCFファイルに書出しておきます。 # system NET "CLOCK" LOC = "P55" | IOSTANDARD = LVCMOS33 ; NET "nRESET" LOC = "P73" | IOSTANDARD = LVCMOS33 ; # G0 NET "ADBUS<0>" LOC = "P1" | IOSTANDARD = LVCMOS33 ; NET "ADBUS<1>" LOC = "P2" | IOSTANDARD = LVCMOS33 ; NET "ADBUS<2>" LOC = "P4" | IOSTANDARD = LVCMOS33 ; NET "ADBUS<3>" LOC = "P5" | IOSTANDARD = LVCMOS33 ; NET "ADBUS<4>" LOC = "P6" | IOSTANDARD = LVCMOS33 ; NET "ADBUS<5>" LOC = "P7" | IOSTANDARD = LVCMOS33 ; NET "ADBUS<6>" LOC = "P8" | IOSTANDARD = LVCMOS33 ; NET "ADBUS<7>" LOC = "P10" | IOSTANDARD = LVCMOS33 ; # G1 NET "ATRG" LOC = "P11" | IOSTANDARD = LVCMOS33 ; NET "DTRG" LOC = "P12" | IOSTANDARD = LVCMOS33 ; NET "WTRG" LOC = "P13" | IOSTANDARD = LVCMOS33 ; NET "RTRG" LOC = "P14" | IOSTANDARD = LVCMOS33 ; NET "SEL" LOC = "P15" | IOSTANDARD = LVCMOS33 ; NET "OE" LOC = "P17" | IOSTANDARD = LVCMOS33 ; # G0B NET "ROUT<0>" LOC = "P141" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "ROUT<1>" LOC = "P140" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "ROUT<2>" LOC = "P137" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "ROUT<3>" LOC = "P135" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "ROUT<4>" LOC = "P132" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "ROUT<5>" LOC = "P131" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "ROUT<6>" LOC = "P130" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "ROUT<7>" LOC = "P129" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; # G1B NET "GOUT<0>" LOC = "P116" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "GOUT<1>" LOC = "P113" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "GOUT<2>" LOC = "P119" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "GOUT<3>" LOC = "P118" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "GOUT<4>" LOC = "P123" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; NET "ASEL" LOC = "P103" | IOSTANDARD = LVCMOS33 ;  モニタ用信号線を1本増やした程度で  UCFファイルに関しては、ほぼ同じです。  バスインタフェースを利用しているので  利用ピン数の範囲内であれば、バス関係  の変更はありません。  テスト用ファームウエアで変更した部分は  コマンドインタプリタの中に、2コマンド  を用意。 switch ( tmp ) { case '0' : send_atrg(0); adra = 0 ; break ; case '1' : send_atrg(1); adra++ ; break ; case '2' : send_atrg(2); adra-- ; break ; case '3' : send_atrg(3); adra += 2048 ; break ; case '4' : send_atrg(4); adrb = 0 ; break ; case '5' : send_atrg(5); adrb++ ; break ; case '6' : send_atrg(6); adrb-- ; break ; case '7' : send_atrg(7); adrb += 2048 ; break ; default : break ; }  コマンドを増やしたので、ヘルプ内容変更。 void show_help(void) { rs_puts("? help") ; crlf(); rs_puts("A handling address") ; crlf(); rs_puts(" A0 clear A port address") ; crlf(); rs_puts(" A1 increase A port address") ; crlf(); rs_puts(" A2 decrease A port address") ; crlf(); rs_puts(" A3 increase A port address with 2048") ; crlf(); rs_puts(" A4 clear B port address") ; crlf(); rs_puts(" A5 increase B port address") ; crlf(); rs_puts(" A6 decrease B port address") ; crlf(); rs_puts(" A7 increase B port address with 2048") ; crlf(); rs_puts("D set data") ; crlf(); rs_puts("W write value to A port ") ; crlf(); rs_puts("R read B port data") ; crlf(); rs_puts("S show values") ; crlf(); }  データリード処理で、ループの回数を  8192まで増やします。 #define ALAST 8192  さらに表示を一部変更します。 void read_loop(void) { UBYTE result ; UBYTE madr[6] ; UWORD i ; /* default */ *(madr+4) = ':'; *(madr+5) = '\0'; /* clear address */ send_atrg(4); /* loop */ for ( i = 0 ; i < ALAST ; i++ ) { /* show address */ if ( (i & MASK0F) == 0 ) { /* calculate address */ *(madr+0) = ((i >> 12) & MASK0F) ; *(madr+1) = ((i >> 8) & MASK0F) ; *(madr+2) = ((i >> 4) & MASK0F) ; *(madr+3) = (i & MASK0F) ; /* convert */ *(madr+0) = asc_hex[*(madr+0)] ; *(madr+1) = asc_hex[*(madr+1)] ; *(madr+2) = asc_hex[*(madr+2)] ; *(madr+3) = asc_hex[*(madr+3)] ; /* show */ rs_puts( madr ); } /* get data */ result = get_bport_val() ; /* show */ put_value(OFF,result); rs_putchar(' '); /* judge new line */ if ( (i & MASK0F) == 15 ) { crlf(); } /* address increment */ send_atrg(5); } }  端末ソフトの表示は、次のようになります。  ヘルプで、コマンドが増えていることも  確認できます。


目次 inserted by FC2 system