目次
前
次
DualPortMemory
最近の市販FPGAには、大抵メモリが積まれています。
内蔵メモリは、Singleポートのメモリではなく
Dualポート型が採用されています。
DulaPortMemoryは、2つのポートを持ち、次の
ような使い方ができるようになっています。
(2つのポートをA、Bとします。)
- A port (Read/Write) B port (Read/Write)
- A port (Read/Write) B port (No use)
- A port (No use) B port (Read/Write)
- A port (Read/Write) B port (Read only)
- A port (Read/Write) B port (Write only)
- A port (Read only) B port (Read/Write)
- A port (Write only) B port (Read/Write)
- A port (Write only) B port (Read only)
- A port (Read only) B port (Write only)
上の組合せには、ビット幅を含めていませんが
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は、シリアルケーブルで
接続します。シリアルインタフェースのコマンド
を決めます。
- ? ヘルプ
- A A、Bポートのアドレス操作
- D Aポートのデータ転送
- W AポートからDualPortMemoryにデータライト
- R BポートからDualPortMemoryのデータリード
- S A、BポートのアドレスとAポートのデータ表示
アドレスは、コマンドとパラメータを指定して
操作します。
- A0 Aポートのアドレスをクリア
- A1 Aポートのアドレスを+1
- A2 Aポートのアドレスを-1
- A4 Bポートのアドレスをクリア
- A5 Bポートのアドレスを+1
- A6 Bポートのアドレスを-1
シリアルインタフェースの仕様は、次のように
決めておきます。
- 3線式(RTSとCTS直結、DTRとDSR直結)
- データ転送速度19200bps
- データ長8ビット
- ストップビット1ビット
- フロー制御なし
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つのポートアドレスを操作します。
- 000 clear A port Address
- 001 A port Address increment (+1)
- 010 A port Address decrement (-1)
- 011 A port Address increment (+2048)
- 100 clear B port Address
- 101 B port Address increment (+1)
- 110 B port Address decrement (-1)
- 111 B port Address increment (+2048)
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);
}
}
端末ソフトの表示は、次のようになります。
ヘルプで、コマンドが増えていることも
確認できます。
目次
前
次