Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • project/gn4124-core
1 result
Show changes
Showing
with 0 additions and 2846 deletions
//---------------------------------------------------------------------------
/*
* Name: vdma_gen.c
*
* Description: Main Program for Generating VDMA Sequencer Code.
*
*/
#include "stdio.h"
#include "ctype.h"
#include "string.h"
#include "stdlib.h"
//#include "malloc.h"
#include "vdma_seqcode.h"
//#include "vdma_gen_struct.h"
#define VDMA_DRAM_SIZE 2048 // Size in DW of the descriptor RAM
#define MAX_LABELS 2048 // Maximum number of labels
#define MAX_COMMENT 200
#define MAX_LABEL_SIZE 32
struct
{
DWORD data;
char *label;
char comment[MAX_COMMENT+1];
} dram[VDMA_DRAM_SIZE+1];
struct
{
char *label; // label string
int address; // Address of the label
} vdma_labels[MAX_LABELS];
int label_compare(char *string1, char *string2)
{
if((string1 == NULL) || (string2 == NULL) || (*string1 == '\0') || (*string2 == '\0'))
return(0); /* no match */
else if(strlen(string1) != strlen(string2))
return(0); /* no match */
else
return(strcmp(string1, string2) == 0);
}
int program_address = 0;
int label_pointer = 0;
char last_label[100];
char out_filename[256];
FILE *outfp;
FILE *infp;
#include "model.c"
#include "vdma_seqcode_lib.c"
#define BAR0_ADDR_H ((DWORD)0xFF000000)
#define BAR0_ADDR_L ((DWORD)0x10000000)
//================================================================================================
//
// Do Some Initialization
//
//================================================================================================
maketest_init(argc,argv)
int argc;
char *argv[];
{
int i;
char *src, *dst;
// char filename[256];
src = argv[0];
dst = out_filename;
for(i=0; i<250; i++)
{
*dst = *src;
if(*src == '\0')
{
dst[0]='.';
dst[1]='h';
dst[2]='e';
dst[3]='x';
dst[4]='\0';
break;
}
if(*src == '.')
{
dst[1]='h';
dst[2]='e';
dst[3]='x';
dst[4]='\0';
break;
}
dst++;
src++;
}
/* Open the Hex Output File */
if((outfp = fopen(out_filename,"wb")) == NULL)
{
fprintf(stderr, "Couldn't open file %s for writing\n", out_filename);
exit(-2);
}
clearerr(outfp);
fprintf(stderr, "Output file %s is open...\n", out_filename);
/* initialize the label structure */
for(i = 0; i < MAX_LABELS; i++)
{
vdma_labels[i].label = NULL;
vdma_labels[i].address = -1;
}
/* initialize the descriptor RAM structure */
for(i = 0; i < VDMA_DRAM_SIZE; i++)
{
dram[i].label = NULL;
dram[i].data = 0;
dram[i].comment[0] = '\0';
}
program_address = 0;
label_pointer = 0;
last_label[0] = '\0';
fprintf(stderr, "Initialization complete\n");
comment("***********************************************************************************");
comment("*** Warning: this file is automatically generated. ***");
comment("***********************************************************************************");
comment("*** Do not edit this file directly as it is not the source! ***");
comment("***********************************************************************************");
}
vdma_process(U64 descriptor_base)
{
int i=0;
int lines=0;
int im;
int address;
fprintf(stderr, "Pass one complete:\n");
fprintf(stderr, " Processed %d labels\n", label_pointer);
fprintf(stderr, " Ended with program address=0x%04X\n", program_address);
//---------------------------------------------------------------------------------
// 2nd Pass: Now resolve label references
//---------------------------------------------------------------------------------
for(program_address = 0; program_address < VDMA_DRAM_SIZE; program_address++)
{
if((dram[program_address].label != NULL) && (dram[program_address].label[0] != '\0')) /* resolve the label */
{
//fprintf(stderr, "Resolving label %s at address=0x%04X\n", dram[program_address].label, program_address);
if(vdma_label_lookup(dram[program_address].label, &address))
{
dram[program_address].data |= address & 0xFFFF;
}
else
{
if((dram[program_address].label[0] == '0') && (tolower(dram[program_address].label[1]) == 'x')) // case of the label being a number
{
if(sscanf(&dram[program_address].label[2], "%x", &im) == 1)
dram[program_address].data |= im & 0xFFFF;
else
fprintf(stderr, "ERROR: could not resolve label %s. Appears to be a hex value?\n", dram[program_address].label);
}
else
fprintf(stderr, "ERROR: could not resolve label %s\n", dram[program_address].label);
}
i++;
}
//fprintf(stderr, "%d\n", program_address);
if(dram[program_address].label != NULL)
{
fprintf(outfp, "0x%04X\t0x%08lX\t%s\n", program_address, dram[program_address].data, dram[program_address].comment);
fprintf(stdout, "-- 0x%04X 0x%08lX %s\n", program_address, dram[program_address].data, dram[program_address].comment);
wr(descriptor_base + (program_address*4), 0xF, dram[program_address].data);
//fprintf(stdout, "wrb %08lX%08lX F %08lX\n", 0xFF000000, program_address, dram[program_address].data);
lines++;
}
}
fprintf(outfp, "// Label Listing:\n");
// Put the label table into the output file
for(i = 0; i < label_pointer; i++)
{
fprintf(outfp, "// 0x%04X : \"%s\"\n", vdma_labels[i].address, vdma_labels[i].label);
}
// label_pointer = 0;
fprintf(stderr, "Pass two complete:\n");
fprintf(stderr, " Substituted %d references in %d words of program and data space\n", i, lines);
fprintf(stderr, " Created output file \"%s\"\n", out_filename);
}
/*----------------------------------------------------------------------------
-- model.c : Generate BFM Commands from C
--
-- This module re-directs bus model commands to specific sub modules.
--
-- For Example:
-- A system simulation that has both a pci32 model and an i960sx model
-- can drive both models from a single file as follows:
--
-- model_map(0, "i960sx"); // model #0 is an i960sx
-- model_map(1, "pci32"); // model #1 is a 32 bit PCI model
-- model(0); // Select the i960sx model
-- memw32(0x100, 0x76543210);
-- memv32(0x100);
-- model(1); // Select the PCI model
-- memw32(0x200, 0x01234567);
-- memv32(0x200);
----------------------------------------------------------------------------*/
#include <stdio.h>
//#include "emul.h"
#define U64 unsigned long long
//#define U64 unsigned long long
#define U32 unsigned long
#define U16 unsigned short
#define U8 unsigned char
#define BYTE unsigned char
#define MAX_MODEL_CHAN 20
int model_num = 0;
int current_channel = 0;
int chan_init = 1;
//extern void set_chan(int chan);
/*----------------------------------------------------------------------------
-- btype: returns an ' ' if an address is at the end of a burst
----------------------------------------------------------------------------*/
char btype(U64 address)
{
U32 mask;
int burst_length, bus_width;
burst_length = 4096;
bus_width = 32;
mask = burst_length - 1;
mask ^= bus_width/8 - 1;
if((address & mask) == mask) /* crosses a burst boundary */
return(' ');
else
return('b');
}
/*----------------------------------------------------------------------------
-- xwrite: Write on a DW boundary with byte enables
-- Primitive used for all writes
----------------------------------------------------------------------------*/
void xwrite(U64 address, BYTE be, U32 data, char burst)
{
fprintf(stdout, "wr%c %016llX %X %08lX\n", burst, address, be, data);
}
/*----------------------------------------------------------------------------
-- xread: Read primitive - reads data ion a DW boundary with byte enables
----------------------------------------------------------------------------*/
void xread(U64 address, BYTE be, U32 data, U32 mask, char burst, char mode)
{
fprintf(stdout, "rd%c %016llX %X %08lX %08lX\n", burst, address, be, data, mask);
}
/*----------------------------------------------------------------------------
-- opr_prn: prints out an array of read, write or verify commands
----------------------------------------------------------------------------*/
void opr_prn(U64 address, BYTE *be, U32 *d, U32 *m, char mode, char burst, int n)
{
int i;
char c;
for(i = 0; i < n; i++)
{
if((n == 1) && (burst == ' '))
c = ' ';
else if((i == (n-1)) && (burst != 'b'))
c = ' ';
else
c = btype(address);
if(mode == 'r')
{
xread(address, be[i], d[i], m[i], c, mode);
}
else if(mode == 'v')
{
xread(address, be[i], d[i], m[i], c, mode);
}
else
{
xwrite(address, be[i], d[i], c);
}
address += 4;
}
}
/*----------------------------------------------------------------------------
-- xopr: 32 bit operations on a 32 bit boundary with byte enables, burst and non-burst
----------------------------------------------------------------------------*/
void xopr(U64 address, BYTE be, U32 data, U32 mask, char burst, char mode)
{
U32 d[2], m[2];
char c;
BYTE b[2];
int n = 1;
/*printf("-- xopr(address=0x%08lX, be=0x%X, data=0x%08lX, masks=0x%08lX, burst=%c, mode=%c)\n", address, be, data, mask, burst, mode);*/
if(address & 3)
{
fprintf(stdout, "-- WARNING: address not 32 bit aligned and will be adjusted\n");
address &= ~3;
}
c = burst;
b[0] = be;
d[0] = data;
m[0] = mask;
opr_prn(address, b, d, m, mode, burst, n);
}
/*----------------------------------------------------------------------------
-- xwr: Write 32 bits on a 32 bit boundary with byte enables, burst and non-burst
----------------------------------------------------------------------------*/
void xwr(U64 address, BYTE be, U32 data, char burst)
{
xopr(address, be, data, 0, burst, 'w');
}
/*----------------------------------------------------------------------------
-- xrd: Read 32 bits on a 32 bit boundary with byte enables, burst and non-burst
----------------------------------------------------------------------------*/
void xrd(U64 address, BYTE be, U32 data, U32 mask, char burst)
{
xopr(address, be, data, mask, burst, 'r');
}
/*----------------------------------------------------------------------------
-- xrv: Verify 32 bits on a 32 bit boundary with byte enables, burst and non-burst
----------------------------------------------------------------------------*/
void xrv(U64 address, BYTE be, char burst)
{
xopr(address, be, 0, 0, burst, 'v');
}
//***********************************************************************************************
//**
//** Commands Specific to the Command Router
//**
//***********************************************************************************************
/*----------------------------------------------------------------------------
-- comment: put a comment in the command file.
----------------------------------------------------------------------------*/
void comment(char *str)
{
while(*str == '\n')
{
printf("\n");
str++;
}
if(*str != '\0')
{
if(*str == '-')
printf("--%s\n", str);
else
printf("-- %s\n", str);
}
}
/*----------------------------------------------------------------------------
-- sync: does the sync command.
----------------------------------------------------------------------------*/
void sync()
{
printf("sync\n");
}
/*----------------------------------------------------------------------------
-- gsync: does the gsync command.
----------------------------------------------------------------------------*/
void gsync()
{
printf("gsync\n");
}
/*----------------------------------------------------------------------------
-- model: Select a model.
----------------------------------------------------------------------------*/
void model(int model)
{
printf("model %%d%d\n", model);
}
/*----------------------------------------------------------------------------
-- ckoff: Turn off the models clock.
----------------------------------------------------------------------------*/
void ckoff()
{
printf("ckoff \n");
}
/*----------------------------------------------------------------------------
-- ckon: Turn on the models clock.
----------------------------------------------------------------------------*/
void ckon()
{
printf("ckon \n");
}
//***********************************************************************************************
//**
//** Model Commands
//**
//***********************************************************************************************
/*----------------------------------------------------------------------------
-- init: Initalize a model.
----------------------------------------------------------------------------*/
void init()
{
printf("init\n");
}
/*----------------------------------------------------------------------------
-- reset: Initalize a model.
----------------------------------------------------------------------------*/
void reset(int n)
{
printf("reset %%d%d\n", n);
}
/*----------------------------------------------------------------------------
-- lclk: lclk period.
----------------------------------------------------------------------------*/
void lclk(int n)
{
printf("lclk %%d%d\n", n);
}
/*----------------------------------------------------------------------------
-- base: base period.
----------------------------------------------------------------------------*/
void base(int n)
{
if((n==2)||(n==10)||(n==16))
{
printf("base %%d%d\n", n);
}
else
{
fprintf(stderr, "ERROR: invalid base specified: %d\n", n);
printf("--ERROR: base \%d%d\n", n);
}
}
/*----------------------------------------------------------------------------
-- bar BAR ADDR SIZE VC TC S
----------------------------------------------------------------------------*/
void bar(int bar, U64 addr, U32 size, int vc, int tc, int s)
{
if(bar != 0) bar = 1;
if(s != 0) s = 1;
if(vc != 0) vc = 1;
if((tc < 0)||(tc > 7)) tc = 0;
printf("bar %d %016llX %08X %X %X %X\n", bar, addr, size, vc, tc, s);
}
/*----------------------------------------------------------------------------
-- bfm_bar BAR ADDR SIZE
----------------------------------------------------------------------------*/
void bfm_bar(int bar, U64 addr, U32 size)
{
if(bar != 0) bar = 1;
printf("bfm_bar %d %016llX %08X\n", bar, addr, size);
}
/*----------------------------------------------------------------------------
-- wait: Do nothing for N CLK cycles
----------------------------------------------------------------------------*/
void wait(int n)
{
fprintf(stdout, "wait %%d%d\n", n);
}
/*----------------------------------------------------------------------------
-- flush: Wait until all outstanding read requests have been completed or
-- N local bus clocks, whichever comes first.
----------------------------------------------------------------------------*/
void flush(int n)
{
fprintf(stdout, "flush %%d%d\n", n);
}
/*----------------------------------------------------------------------------
-- rd_outstanding_in: Number of outstanding read commands allowed incoming to the model
--
----------------------------------------------------------------------------*/
void rd_outstanding_in(int n)
{
if((n < 1)||(n > 4)) n = 3;
fprintf(stdout, "rd_outstanding_in %%d%d\n", n);
}
/*----------------------------------------------------------------------------
-- rd_outstanding_out: Number of outstanding read before the BFM will stall
--
----------------------------------------------------------------------------*/
void rd_outstanding_out(int n)
{
if((n < 1)||(n > 4)) n = 3;
fprintf(stdout, "rd_outstanding_out %%d%d\n", n);
}
/*----------------------------------------------------------------------------
-- response_delay: Delay the return of response data by N local bus clock intervals
--
----------------------------------------------------------------------------*/
void response_delay(int n, int vc)
{
if(vc != 0) vc = 1;
fprintf(stdout, "response_delay %%d%d %d\n", n, vc);
}
/*----------------------------------------------------------------------------
-- burst_length: Sets the burst length that read/write packets will get truncated to.
--
----------------------------------------------------------------------------*/
void burst_length(int n, int bar)
{
if(bar != 0) bar = 1;
fprintf(stdout, "burst_length %%d%d %d\n", n, bar);
}
/*----------------------------------------------------------------------------
-- burst_modulo: Sets the burst length that read/write packets will get truncated to.
--
----------------------------------------------------------------------------*/
void burst_modulo(int n, int bar)
{
if(bar != 0) bar = 1;
fprintf(stdout, "burst_modulo %%d%d %d\n", n, bar);
}
/*----------------------------------------------------------------------------
-- cpl_modulo: Sets the burst length that read/write packets will get truncated to.
--
----------------------------------------------------------------------------*/
void cpl_modulo(int n)
{
fprintf(stdout, "cpl_modulo %%d%d\n", n);
}
/*----------------------------------------------------------------------------
-- cpl_order: Sets the burst length that read/write packets will get truncated to.
--
----------------------------------------------------------------------------*/
void cpl_order(int n)
{
fprintf(stdout, "cpl_order %%d%d\n", n);
}
/*----------------------------------------------------------------------------
-- iwait_random: Initiator random wait state insertion
--
----------------------------------------------------------------------------*/
void iwait_random(int p, int n)
{
if((p < 0)||(p > 100)) p = 0;
if(p==0)
fprintf(stdout, "iwait_random %%d%d 0 -- Initiator random wait states disabled\n", p);
else
fprintf(stdout, "iwait_random %%d%d %%d%d -- Initiator random wait states: probability=%d%% max duration= %d\n", p, n, p, n);
}
/*----------------------------------------------------------------------------
-- gpio_wait N P MASK: Wait for N local bus clock intervals for GPIO to reach a defined state.
--
----------------------------------------------------------------------------*/
void gpio_wait(int n, U32 p, U32 mask)
{
fprintf(stdout, "gpio_wait %%d%d %04lX %04lX -- gpio_wait N P MASK\n", n, p, mask);
}
/*----------------------------------------------------------------------------
-- l2p_rdy STATE DURATION R: Drive the L2P_RDY signal to STATE for
-- duration DURATION as a number of local bus
-- clock intervals.
--
----------------------------------------------------------------------------*/
void l2p_rdy(char state, int duration, int r)
{
fprintf(stdout, "l2p_rdy %c %%%d %%%d -- l2p_rdy STATE DURATION RESTART\n", state, duration, r);
}
/*----------------------------------------------------------------------------
-- vc VC: Set the virtual channel number for subsequent P2L read/write
-- requests on the local bus.
--
----------------------------------------------------------------------------*/
void vc(int vc)
{
fprintf(stdout, "vc %X\n", vc);
}
//l_wr_rdy FILL DRAIN
/*----------------------------------------------------------------------------
-- ************************** User Visible Functions ***********************
--
-- The following functions are to be used in the user source code
----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
-- wr: Non-Burst Write 32 bits on a 32 bit boundary with byte enables
----------------------------------------------------------------------------*/
void wr(U64 address, BYTE be, U32 data)
{
xwr(address, be, data, ' ');
}
/*----------------------------------------------------------------------------
-- rd: Non-Burst Read 32 bits on a 32 bit boundary with byte enables
----------------------------------------------------------------------------*/
void rd(U64 address, BYTE be, U32 data, U32 mask)
{
xrd(address, be, data, mask, ' ');
}
/*----------------------------------------------------------------------------
-- rv: Non-Burst Read Verify 32 bits on a 32 bit boundary with byte enables
----------------------------------------------------------------------------*/
void rv(U64 address, BYTE be)
{
xrv(address, be, ' ');
}
/*----------------------------------------------------------------------------
-- wrb: Burst Write 32 bits on a 32 bit boundary with byte enables
----------------------------------------------------------------------------*/
void wrb(U64 address, BYTE be, U32 data)
{
xwr(address, be, data, 'b');
}
/*----------------------------------------------------------------------------
-- rdb: Burst Read 32 bits on a 32 bit boundary with byte enables
----------------------------------------------------------------------------*/
void rdb(U64 address, BYTE be, U32 data, U32 mask)
{
xrd(address, be, data, mask, 'b');
}
/*----------------------------------------------------------------------------
-- rvb: Burst Read Verify 32 bits on a 32 bit boundary with byte enables
----------------------------------------------------------------------------*/
void rvb(U64 address, BYTE be)
{
xrv(address, be, 'b');
}
/*----------------------------------------------------------------------------
-- opr32: Primitive for 32 bits on any byte boundary
----------------------------------------------------------------------------*/
void opr32(U64 address, U32 data, U32 mask, char mode)
{
U32 d[2], m[2], step;
BYTE be[2];
int n, i;
char c;
step = 4;
if((address & 0x3) != 0) /* on an odd word boundary */
{
d[0] = data << (8 * (address & 3));
d[1] = data >> (8 * (4 - (address & 3)));
m[0] = mask << (8 * (address & 3));
m[1] = mask >> (8 * (4 - (address & 3)));
be[0] = (0xF << (address & 3) ) & 0xF;
be[1] = (0xF >> (4-(address & 3))) & 0xF;
address &= ~3;
n = 2;
}
else /* even boundary */
{
d[0] = data;
m[0] = mask;
be[0] = 0xF;
n = 1;
}
opr_prn(address, be, d, m, mode, ' ', n);
}
/*----------------------------------------------------------------------------
-- wr32: Write 32 bits on any byte boundary
----------------------------------------------------------------------------*/
void wr32(U64 address, U32 data)
{
opr32(address, data, 0, 'w');
}
/*----------------------------------------------------------------------------
-- rd32: Read 32 bits on any byte boundary
----------------------------------------------------------------------------*/
void rd32(U64 address, U32 data, U32 mask)
{
opr32(address, data, mask, 'r');
}
/*----------------------------------------------------------------------------
-- opr16: Primitive for 16 bit operations on any byte boundary
----------------------------------------------------------------------------*/
void opr16(U64 address, U16 data, U16 mask, char mode)
{
U32 d[2], m[2];
BYTE be[2];
int n;
if((address & 0x3) == 0x3) /* on an odd word boundary */
{
d[0] = (U32) data << 24;
d[1] = (U32) data >> 8;
m[0] = (U32) mask << 24;
m[1] = (U32) mask >> 8;
be[0] = 0x8;
be[1] = 0x1;
address &= ~3;
n = 2;
}
else /* even boundary */
{
d[0] = (U32) data << (8 * (address & 0x3));
m[0] = (U32) mask << (8 * (address & 0x3));
be[0] = 3 << (address & 0x3);
address &= ~3;
n = 1;
}
opr_prn(address, be, d, m, mode, ' ', n);
}
/*----------------------------------------------------------------------------
-- wr16: Write 16 bits on any byte boundary
----------------------------------------------------------------------------*/
void wr16(U64 address, U16 data)
{
opr16(address, data, 0, 'w');
}
/*----------------------------------------------------------------------------
-- rd16: Read 16 bits on any byte boundary
----------------------------------------------------------------------------*/
void rd16(U64 address, U16 data, U16 mask)
{
opr16(address, data, mask, 'r');
}
/*----------------------------------------------------------------------------
-- opr8: adjust 8 bits on any byte boundary
----------------------------------------------------------------------------*/
void opr8(U64 address, U16 data, U16 mask, char mode)
{
U32 a, d, m;
BYTE be;
U64 amask;
amask = 3;
d = ((U32) data & 0xFF) << (8 * (address & amask));
m = ((U32) mask & 0xFF) << (8 * (address & amask));
be = 1 << (address & amask);
a = address & (~amask);
opr_prn(a, &be, &d, &m, mode, ' ', 1);
}
/*----------------------------------------------------------------------------
-- wr8: Write 8 bits on any byte boundary
----------------------------------------------------------------------------*/
void wr8(U64 address, U16 data)
{
opr8(address, data, 0, 'w');
}
/*----------------------------------------------------------------------------
-- rd8: Read 8 bits on any byte boundary
----------------------------------------------------------------------------*/
void rd8(U64 address, U16 data, U16 mask)
{
opr8(address, data, mask, 'r');
}
/*----------------------------------------------------------------------------
-- swap8: 8 bit swap on 32 bit data
----------------------------------------------------------------------------*/
U32 swap8(U32 data)
{
data = (data << 24) | ((data << 8) & 0x00ff0000) | ((data >> 8) & 0x0000ff00) | (data >> 24);
return data;
}
/*----------------------------------------------------------------------------
-- swap16: 16 bit swap on 32 bit data
----------------------------------------------------------------------------*/
U32 swap16(U32 data)
{
data = (data << 16) | (data >> 16);
return data;
}
//---------------------------------------------------------------------------
/*
* Name: vdma_seqcode.h
*
* Description: FlexDMA sequencer instruction macros.
*
*/
#ifndef _VDMA_SEQCODE_H_
#define _VDMA_SEQCODE_H_
//Warning message during compilation to indicate macros are used
#pragma message("***** VDMA_CODE_GEN_MACRO is defined *****")
#ifndef DWORD
#define DWORD unsigned long
#endif
/*************************************************
VDMA sequencer code Definitions
*************************************************/
#define _IM (0)
#define _RA (2)
#define _RB (3)
//Condition code for JMP instruction
#define _RA_EQZ (0x8)
#define _RA_NEQZ (0)
#define _RB_EQZ (0x9)
#define _RB_NEQZ (1)
#define _ALWAYS (0xA)
#define _NEVER (0x2)
#define _C_HI (0xB)
#define _C_LO (0x3)
#define _PDM_CMD_QUEUE_FULL_HI (0xC)
#define _PDM_CMD_QUEUE_FULL_LO (0x4)
#define _LDM_CMD_QUEUE_FULL_HI (0xD)
#define _LDM_CMD_QUEUE_FULL_LO (0x5)
#define _EXT_COND_HI (0xF)
#define _EXT_COND_LO (0x7)
//External condition select code for JMP instruction
#define _PDM_IDLE (32)
#define _LDM_IDLE (33)
#define _EXT_COND_0 (34)
#define _EXT_COND_1 (35)
#define _EXT_COND_2 (36)
#define _EXT_COND_3 (37)
#define _EXT_COND_4 (38)
#define _EXT_COND_5 (39)
#define _EXT_COND_6 (40)
#define _EXT_COND_7 (41)
#define _EXT_COND_8 (42)
#define _EXT_COND_9 (43)
#define _EXT_COND_10 (44)
#define _EXT_COND_11 (45)
#define _EXT_COND_12 (46)
#define _EXT_COND_13 (47)
#define _EXT_COND_14 (48)
#define _EXT_COND_15 (49)
// VDMA instructions
#define VDMA_NOP() \
((DWORD)0x0)
#define VDMA_LOAD_SYS_ADDR(R, ADDR) \
((DWORD)0x40000000 | \
((DWORD)(R & 0x3) << 24) | \
((DWORD)(ADDR & 0xFFFF)) \
)
#define VDMA_STORE_SYS_ADDR(R, ADDR) \
((DWORD)0x50000000 | \
((DWORD)(R & 0x3) << 24) | \
((DWORD)(ADDR & 0xFFFF)) \
)
#define VDMA_ADD_SYS_ADDR(DATA) \
((DWORD)0x60000000 | \
((DWORD)(DATA & 0xFFFF)) \
)
#define VDMA_ADD_SYS_ADDR_I(ADDR) \
((DWORD)0xE0000000 | \
((DWORD)(ADDR & 0xFFFF)) \
)
#define VDMA_LOAD_XFER_CTL(R, ADDR) \
((DWORD)0xF0000000 | \
((DWORD)(R & 0x3) << 24) | \
((DWORD)(ADDR & 0xFFFF)) \
)
#define VDMA_LOAD_RA(ADDR) \
((DWORD)0x20000000 | \
((DWORD)(ADDR & 0xFFFF)) \
)
#define VDMA_ADD_RA(ADDR) \
((DWORD)0x21000000 | \
((DWORD)(ADDR & 0xFFFF)) \
)
#define VDMA_LOAD_RB(ADDR) \
((DWORD)0x24000000 | \
((DWORD)(ADDR & 0xFFFF)) \
)
#define VDMA_ADD_RB(ADDR) \
((DWORD)0x25000000 | \
((DWORD)(ADDR & 0xFFFF)) \
)
#define VDMA_STORE_RA(ADDR) \
((DWORD)0xA2000000 | \
((DWORD)(ADDR & 0xFFFF)) \
)
#define VDMA_STORE_RB(ADDR) \
((DWORD)0xA3000000 | \
((DWORD)(ADDR & 0xFFFF)) \
)
#define VDMA_JMP(C, EXT_COND, ADDR) \
((DWORD)0x10000000 | \
(DWORD)((C & 0xF) << 24) | \
(DWORD) ((EXT_COND & 0xFF) << 16) | \
((DWORD)(ADDR & 0xFFFF)) \
)
#define VDMA_SIG_EVENT(S, A, EVENT_EN) \
((DWORD)0x80000000 | \
((DWORD)(S & 0x1) << 27) | \
((DWORD)(A & 0x1) << 26) | \
((DWORD)(EVENT_EN & 0xFFFF)) \
)
#define VDMA_WAIT_EVENT(EVENT_EN, EVENT_STATE) \
((DWORD)0x90000000 | \
((DWORD)((EVENT_EN & 0xFFF) << 12)) | \
((DWORD)(EVENT_STATE & 0xFFF)) \
)
#endif
//---------------------------------------------------------------------------
/*
* Name: vdma_seqcode_lib.h
*
* Description: FlexDMA sequencer functions used for the first pass compile.
*
*/
// Data structure for a 3 or 4 word scatter/gather entry
struct sg_entry_struct
{
U64 address;
U32 vdma_xfer_ctl;
U32 vdma_xfer_rpt; /* in a 3-word SG entry this is unused */
};
//================================================================================================
//
// Note: all references are symbolic at this level
//
//================================================================================================
void next_address()
{
//fprintf(stderr, "program_address=0x%04X\n", program_address);
program_address++;
if(dram[program_address].label != NULL)
{
fprintf(stderr, "WARNING: next program_address 0x%04X has already been used\n", program_address);
}
sprintf(last_label, "%s ", "");
if(program_address >= VDMA_DRAM_SIZE)
{
fprintf(stderr, "ERROR: descriptor RAM address (%d) exceeded maximum (max=%d)\n", program_address, VDMA_DRAM_SIZE);
exit(-91);
}
}
char *r_to_string(int r)
{
switch(r)
{
case _IM:
return("_IM");
break;
case _RA:
return("_RA");
break;
case _RB:
return("_RB");
break;
default:
return("ERROR");
}
}
char *c_to_string(int c)
{
switch(c)
{
case _RA_EQZ:
return("_RA_EQZ");
break;
case _RA_NEQZ:
return("_RA_NEQZ");
break;
case _RB_EQZ:
return("_RB_EQZ");
break;
case _RB_NEQZ:
return("_RB_NEQZ");
break;
case _ALWAYS:
return("_ALWAYS");
break;
case _NEVER:
return("_NEVER");
break;
case _C_HI:
return("_C_HI");
break;
case _C_LO:
return("_C_LO");
break;
case _PDM_CMD_QUEUE_FULL_HI:
return("_PDM_CMD_QUEUE_FULL_HI");
break;
case _PDM_CMD_QUEUE_FULL_LO:
return("_PDM_CMD_QUEUE_FULL_LO");
break;
case _LDM_CMD_QUEUE_FULL_HI:
return("_LDM_CMD_QUEUE_FULL_HI");
break;
case _LDM_CMD_QUEUE_FULL_LO:
return("_LDM_CMD_QUEUE_FULL_LO");
break;
case _EXT_COND_HI:
return("_EXT_COND_HI");
break;
case _EXT_COND_LO:
return("_EXT_COND_LO");
break;
default:
return("ERROR");
}
}
char *ext_cond_to_string(int e, int c)
{
static char estr[20];
if((c == _EXT_COND_HI) || (c == _EXT_COND_LO))
{
switch(e)
{
case _PDM_IDLE:
return("_PDM_IDLE");
break;
case _LDM_IDLE:
return("_LDM_IDLE");
break;
default:
if((e >= 0) && (e <= 15))
{
sprintf(estr, "_EVENT_%d", e);
return(estr);
} else if(e >= _EXT_COND_0)
{
sprintf(estr, "_EXT_COND_%d", e - _EXT_COND_0);
return(estr);
} else
{
return("ERROR");
}
break;
}
}
return("NA");
}
//================================================================================================
//
// string_cat(char *base, char *extension): create a new string by concatenating two strings
//
//================================================================================================
char *string_cat(char *beginning, char *end)
{
char *ptr;
ptr = (char *) malloc(strlen(beginning)+strlen(end)+1);
if(ptr == NULL)
{
fprintf(stderr, "ERROR: could not allocate memory in function string_cat\n");
exit(111);
}
sprintf(ptr, "%s%s", beginning, end);
return(ptr);
}
//================================================================================================
//
// vdma_org(int address): change the program pointer to address
//
//================================================================================================
void vdma_org(int address)
{
program_address = address;
}
//================================================================================================
//
// vdma_label_lookup(char *str, int *value): find a label and store its value at *value.
//
//================================================================================================
int vdma_label_lookup(char *str, int *value)
{
int i;
for(i = 0; i < label_pointer; i++)
{
if(label_compare(str, vdma_labels[i].label))
{
*value = vdma_labels[i].address;
return(1);
}
}
return(0);
}
//================================================================================================
//
// vdma_label(char *label): set a label at the current address
//
//================================================================================================
void vdma_label(char *label)
{
int i;
fprintf(stderr, "Label[%d]: %s=0x%04X\n", label_pointer, label, program_address);
if(strlen(label) > MAX_LABEL_SIZE)
{
fprintf(stderr, "ERROR: label \"%s\" exceedes the maximum length of %d\n", label, MAX_LABEL_SIZE);
exit(-89);
}
if(label_pointer !=0)
{
/* make sure the label has not been previously declared */
for(i = 0; i < label_pointer; i++)
{
//fprintf(stderr, "label_compare(label=%s, vdma_labels[i=%d].label=%s)\n", label, i, vdma_labels[i].label);
if(label_compare(label, vdma_labels[i].label))
{
//fprintf(stderr, "label_compare(label=%s, vdma_labels[i=%d].label=%s)\n", label, i, vdma_labels[i].label);
fprintf(stderr, "ERROR: the label \"%s\" has already been declared at label[%d] with address=0x%04X\n", label, i, vdma_labels[i].address);
break;
}
}
}
vdma_labels[label_pointer].address = program_address;
vdma_labels[label_pointer].label = label;
sprintf(last_label, "%s:", label);
label_pointer++;
if(label_pointer >= MAX_LABELS)
{
fprintf(stderr, "ERROR: to many labels specified (max=%d)\n", MAX_LABELS);
exit(-90);
}
}
//================================================================================================
//
// vdma_constant_l(char *label): set a constant to equal the address value of a label
//
//================================================================================================
void vdma_constant_l(char *label)
{
dram[program_address].data = 0;
dram[program_address].label = label;
sprintf(dram[program_address].comment, "%24s vdma_constant_l(\"%s\")", last_label, label);
next_address();
}
//================================================================================================
//
// vdma_constant_n(DWORD data): set a constant to a numerical value at the current address
//
//================================================================================================
void vdma_constant_n(DWORD data)
{
dram[program_address].data = data;
dram[program_address].label = "";
sprintf(dram[program_address].comment, "%24s vdma_constant_n(0x%08lX)", last_label, data);
next_address();
}
//================================================================================================
//
// vdma_constant_n64(U64 data): same as vdma_constant_n except for 64-bit data
//
//================================================================================================
void vdma_constant_n64(U64 data)
{
DWORD d32;
d32 = data & 0xFFFFFFFF;
dram[program_address].data = d32;
dram[program_address].label = "";
sprintf(dram[program_address].comment, "%24s vdma_constant_n64(0x%016llX)", last_label, data);
next_address();
d32 = (DWORD)(data >> (U64) 32);
dram[program_address].data = d32;
dram[program_address].label = "";
sprintf(dram[program_address].comment, "%24s // vdma_constant_n64 - upper data", last_label);
next_address();
}
//================================================================================================
//
// vdma_array(DWORD data, int n): initializes an array of data at the current address with the same data
//
//================================================================================================
void vdma_array(DWORD data, int n)
{
int i;
for(i=0; i<n; i++)
{
dram[program_address].data = data;
dram[program_address].label = "";
if(i==0)
sprintf(dram[program_address].comment, "%24s vdma_array(0x%lX, %d)", last_label, data, n);
else
sprintf(dram[program_address].comment, "%24s // %s[%d]", "", vdma_labels[label_pointer-1].label, i);
next_address();
}
}
//************************************************************************************************
//
// all functions from here on map directly to the VDMA instructions documented in the
// GN412x FlexDMA Sequencer Design Guide except that all addresses are specified using labels.
//
//************************************************************************************************
void vdma_nop()
{
dram[program_address].data = VDMA_NOP();
dram[program_address].label = "";
sprintf(dram[program_address].comment, "%24s vdma_nop()", last_label);
next_address();
}
void vdma_load_sys_addr(int r, char *label)
{
dram[program_address].data = VDMA_LOAD_SYS_ADDR(r, 0);
dram[program_address].label = label;
sprintf(dram[program_address].comment, "%24s vdma_load_sys_addr(r=%s, \"%s\")", last_label, r_to_string(r), label);
next_address();
}
void vdma_store_sys_addr(int r, char *label)
{
dram[program_address].data = VDMA_STORE_SYS_ADDR(r, 0);
dram[program_address].label = label;
sprintf(dram[program_address].comment, "%24s vdma_store_sys_addr(r=%s, \"%s\")", last_label, r_to_string(r), label);
next_address();
}
void vdma_add_sys_addr(int data)
{
dram[program_address].data = VDMA_ADD_SYS_ADDR(data);
dram[program_address].label = "";
sprintf(dram[program_address].comment, "%24s vdma_add_sys_addr(%d)", last_label, data);
next_address();
}
void vdma_add_sys_addr_i(char *label)
{
dram[program_address].data = VDMA_ADD_SYS_ADDR_I(0);
dram[program_address].label = label;
sprintf(dram[program_address].comment, "%24s vdma_add_sys_addr_i(\"%s\")", last_label, label);
next_address();
}
void vdma_load_xfer_ctl(int r, char *label)
{
dram[program_address].data = VDMA_LOAD_XFER_CTL(r, 0);
dram[program_address].label = label;
sprintf(dram[program_address].comment, "%24s vdma_load_xfer_ctl(%s, \"%s\")", last_label, r_to_string(r), label);
next_address();
}
void vdma_load_ra(char *label)
{
dram[program_address].data = VDMA_LOAD_RA(0);
dram[program_address].label = label;
sprintf(dram[program_address].comment, "%24s vdma_load_ra(\"%s\")", last_label, label);
next_address();
}
void vdma_add_ra(char *label)
{
dram[program_address].data = VDMA_ADD_RA(0);
sprintf(dram[program_address].comment, "%24s vdma_add_ra(\"%s\")", last_label, label);
dram[program_address].label = label;
next_address();
}
void vdma_load_rb(char *label)
{
dram[program_address].data = VDMA_LOAD_RB(0);
dram[program_address].label = label;
sprintf(dram[program_address].comment, "%24s vdma_load_rb(\"%s\")", last_label, label);
next_address();
}
void vdma_add_rb(char *label)
{
dram[program_address].data = VDMA_ADD_RB(0);
dram[program_address].label = label;
sprintf(dram[program_address].comment, "%24s vdma_add_rb(\"%s\")", last_label, label);
next_address();
}
void vdma_store_ra(char *label)
{
dram[program_address].data = VDMA_STORE_RA(0);
dram[program_address].label = label;
sprintf(dram[program_address].comment, "%24s vdma_store_ra(\"%s\")", last_label, label);
next_address();
}
void vdma_store_rb(char *label)
{
dram[program_address].data = VDMA_STORE_RB(0);
dram[program_address].label = label;
sprintf(dram[program_address].comment, "%24s vdma_store_rb(\"%s\")", last_label, label);
next_address();
}
void vdma_jmp(int c, int ext_cond, char *label)
{
dram[program_address].data = VDMA_JMP(c, ext_cond, 0);
dram[program_address].label = label;
sprintf(dram[program_address].comment, "%24s vdma_jmp(c=%s, ext_cond=%s, \"%s\")", last_label, c_to_string(c), ext_cond_to_string(ext_cond, c), label);
next_address();
}
void vdma_sig_event(int s, int a, int event_en)
{
dram[program_address].data = VDMA_SIG_EVENT(s, a, event_en);
dram[program_address].label = "";
sprintf(dram[program_address].comment, "%24s vdma_sig_event(s=%d, a=%d, event_en=0x%04X)", last_label, s, a, event_en);
next_address();
}
void vdma_wait_event(int event_en, int event_state)
{
dram[program_address].data = VDMA_WAIT_EVENT(event_en, event_state);
dram[program_address].label = "";
sprintf(dram[program_address].comment, "%24s vdma_sig_event(event_en=0x%04X, event_state=0x%04X)", last_label, event_en, event_state);
next_address();
}
//***********************************************************************************************
//***********************************************************************************************
//**
//** Name: vdma_service.c
//**
//** Description: General-Purpose DMA Servicing Routines for a 3DW list and a 4DW list.
//**
//** The following function calls will get invoked from a main program. When the main program
//** is compiled and converted, it will result in a series of write cycles that the BFM
//** will write to the microcode descriptor memory.
//**
//***********************************************************************************************
int data_address = 0; //This will be used to track the data space
//***********************************************************************************************
//**
//** vdma_channel_service_3: This is a generic channel servicing function for 3DW list type.
//** Should be called once for each channel.
//**
//***********************************************************************************************
void vdma_channel_service_3
(
char *base_label, //label to be used for this specific channel
char direction, //direction='l' for l2p or 'p' for p2l
int event_reg, //The event register bit to be used for interrupt generation
int ext_cond, //External condition used for this channel
int condition, //Set to either _EXT_COND_LO or _EXT_COND_HI
int dynamic_list, //set to non zero when the list will be updated dynamicaly
int sg_size, //SYS_ADDR step size of list entries that have a repeat count
struct sg_entry_struct *sg_list
)
{
int cmd_queue_full;
int tmp_address;
int i;
if(direction == 'p')
cmd_queue_full = _PDM_CMD_QUEUE_FULL_HI;
else
cmd_queue_full = _LDM_CMD_QUEUE_FULL_HI;
//---------------------------------------------------------------------------------------------
// Create the program microcode for this channel
//---------------------------------------------------------------------------------------------
vdma_label(base_label);
vdma_jmp(condition, ext_cond, string_cat(base_label, "_END")); //Skip if servicing not required
vdma_jmp(cmd_queue_full, 0, string_cat(base_label, "_END")); //Skip if dma is busy
vdma_load_rb(string_cat(base_label, "_INDEX")); //Load the SG list pointer
vdma_load_sys_addr(_RB,"0x0"); //Load system address from SG entry
vdma_load_xfer_ctl(_RB,"0x2"); //Start DMA1
vdma_jmp(_C_LO, 0, string_cat(base_label, "_NO_INT")); //Need to assert an interrupt?
vdma_sig_event(0, 1, 1<<event_reg); //Assert EVENT(event_reg)
vdma_load_xfer_ctl(_IM,"ZERO"); //Clear C bit
vdma_label(string_cat(base_label, "_NO_INT"));
if(dynamic_list)
{
vdma_load_sys_addr(0,"ZERO"); //Clear the system address register
vdma_store_sys_addr(_RB,"0x1"); //Clear the VDMA_XFER_CTL entry in SG list
}
vdma_add_rb("THREE"); //Advance SG list pointer
vdma_load_ra(string_cat(base_label, "_CNT")); //Load the SG list pointer
vdma_add_ra("MINUS1"); //Subtract 1 from L2P SG list counter
vdma_jmp(_RA_NEQZ, 0, string_cat(base_label, "_UPDATE")); //See if the list needs to wrap around
vdma_load_ra(string_cat(base_label, "_SIZE")); //Restart the list counter
vdma_load_rb(string_cat(base_label, "_BASE")); //Restart the list pointer
vdma_label(string_cat(base_label, "_UPDATE"));
vdma_store_ra(string_cat(base_label, "_CNT")); //Update _CNT
vdma_store_rb(string_cat(base_label, "_INDEX")); //Update _INDEX
vdma_label(string_cat(base_label, "_END"));
//---------------------------------------------------------------------------------------------
// Create the data space for this channel
//---------------------------------------------------------------------------------------------
tmp_address = program_address; //Save away the current program address
vdma_org(data_address);
//-----------------------------------------------
// Local constants
//-----------------------------------------------
vdma_label(string_cat(base_label, "_SIZE"));
vdma_constant_n(sg_size);
vdma_label(string_cat(base_label, "_BASE"));
vdma_constant_l(string_cat(base_label, "_LIST"));
//-----------------------------------------------
// Local variables
//-----------------------------------------------
vdma_label(string_cat(base_label, "_INDEX"));
vdma_constant_l(string_cat(base_label, "_LIST"));
vdma_label(string_cat(base_label, "_CNT"));
vdma_constant_n(sg_size);
//-----------------------------------------------
// SG List storage
//-----------------------------------------------
vdma_label(string_cat(base_label, "_LIST"));
for(i=0; i<sg_size; i++)
{
vdma_constant_n64(sg_list[i].address);
vdma_constant_n( sg_list[i].vdma_xfer_ctl);
}
data_address = program_address; //Save back the current data address
vdma_org(tmp_address); //Restore the program address
}
//***********************************************************************************************
//**
//** vdma_channel_service4: This is a generic channel servicing function for use with 4DW list type.
//**
//***********************************************************************************************
void vdma_channel_service_4
(
char *base_label, //label to be used for this specific channel
char direction, //direction='l' for l2p or 'p' for p2l
int event_reg, //The event register bit to be used for interrupt generation
int ext_cond, //External condition used for this channel
int condition, //Set to either _EXT_COND_LO or _EXT_COND_HI
int dynamic_list, //set to non zero when the list will be updated dynamicaly
int sg_size, //SYS_ADDR step size of list entries that have a repeat count
int sys_addr_increment, //Step size of list entries that have a repeat count
struct sg_entry_struct *sg_list
)
{
int cmd_queue_full;
int tmp_address;
int i;
if(direction == 'p')
cmd_queue_full = _PDM_CMD_QUEUE_FULL_HI;
else
cmd_queue_full = _LDM_CMD_QUEUE_FULL_HI;
//---------------------------------------------------------------------------------------------
// Create the program microcode for this channel
//---------------------------------------------------------------------------------------------
vdma_label(base_label);
vdma_jmp(_EXT_COND_LO, ext_cond, string_cat(base_label, "_END")); //Skip if servicing not required
vdma_jmp(cmd_queue_full, 0, string_cat(base_label, "_END")); //Skip if dma is busy
vdma_load_rb(string_cat(base_label, "_INDEX")); //Load the SG list pointer
vdma_load_ra(string_cat(base_label, "_RPT")); //Load the previous repeat counter
vdma_jmp(_RA_NEQZ, 0, string_cat(base_label, "_RPT_NOT_DONE")); //jmp if previous repeat not done
vdma_load_sys_addr(_RB,"0x3"); //Load repeat count from SG entry
vdma_store_sys_addr(_IM,string_cat(base_label, "_RPT")); //Store to repeat count variable
vdma_load_ra(string_cat(base_label, "_RPT")); //Load the new repeat counter
vdma_jmp(_RA_EQZ, 0, string_cat(base_label, "_NEXT_DESC")); //jmp if the rpt=0
vdma_load_sys_addr(_RB,"0x0"); //Load system address from SG entry
vdma_store_sys_addr(_IM,string_cat(base_label, "_SYSA")); //Store sys address to local variable
vdma_label(string_cat(base_label, "_RPT_NOT_DONE"));
vdma_add_ra("MINUS1"); //Decrement the repeat counter
vdma_load_sys_addr(_IM,string_cat(base_label, "_SYSA")); //Load system address from local variable
vdma_load_xfer_ctl(_RB,"0x2"); //Start DMA1
vdma_jmp(_C_LO, 0, string_cat(base_label, "_NO_INT")); //No interrupt if C=0
vdma_jmp(_RA_NEQZ, 0, string_cat(base_label, "_NO_INT")); //No interrupt if RA!=0
vdma_sig_event(0, 1, 1<<event_reg); //Assert EVENT(event_reg)
vdma_load_xfer_ctl(_IM,"ZERO"); //Clear C bit
vdma_label(string_cat(base_label, "_NO_INT"));
vdma_store_ra(string_cat(base_label, "_RPT")); //Update _RPT
vdma_add_sys_addr(sys_addr_increment); //update the system address
vdma_store_sys_addr(_IM,string_cat(base_label, "_SYSA")); //Store updated sys address to local variable
vdma_jmp(_RA_NEQZ, 0, string_cat(base_label, "_UPDATE_B")); //jmp if repeat count not done
if(dynamic_list)
{
vdma_load_sys_addr(0,"ZERO"); //Clear the system address register
vdma_store_sys_addr(_RB,"0x2"); //Clear the VDMA_XFER_CTL entry in SG list
}
vdma_label(string_cat(base_label, "_NEXT_DESC"));
vdma_add_rb("FOUR"); //Advance SG list pointer
vdma_load_ra(string_cat(base_label, "_CNT")); //Load the SG list counter
vdma_add_ra("MINUS1"); //Subtract 1 from L2P SG list counter
vdma_jmp(_RA_NEQZ, 0, string_cat(base_label, "_UPDATE")); //See if the list needs to wrap around
vdma_load_ra(string_cat(base_label, "_SIZE")); //Restart the list counter
vdma_load_rb(string_cat(base_label, "_BASE")); //Restart the list pointer
vdma_label(string_cat(base_label, "_UPDATE"));
vdma_store_ra(string_cat(base_label, "_CNT")); //Update _CNT
vdma_label(string_cat(base_label, "_UPDATE_B"));
vdma_store_rb(string_cat(base_label, "_INDEX")); //Update _INDEX
vdma_label(string_cat(base_label, "_END"));
//---------------------------------------------------------------------------------------------
// Create the data space for this channel
//---------------------------------------------------------------------------------------------
tmp_address = program_address; //Save away the current program address
vdma_org(data_address);
//-----------------------------------------------
// Local constants
//-----------------------------------------------
vdma_label(string_cat(base_label, "_SIZE"));
vdma_constant_n(sg_size);
vdma_label(string_cat(base_label, "_BASE"));
vdma_constant_l(string_cat(base_label, "_LIST"));
//-----------------------------------------------
// Local variables
//-----------------------------------------------
vdma_label(string_cat(base_label, "_INDEX"));
vdma_constant_l(string_cat(base_label, "_LIST"));
vdma_label(string_cat(base_label, "_CNT"));
vdma_constant_n(sg_size);
vdma_label(string_cat(base_label, "_RPT"));
vdma_constant_n(0);
vdma_constant_n(0); //Need to pad out the repeat count
vdma_label(string_cat(base_label, "_SYSA"));
vdma_constant_n64(0);
//-----------------------------------------------
// SG List storage
//-----------------------------------------------
vdma_label(string_cat(base_label, "_LIST"));
for(i=0; i<sg_size; i++)
{
vdma_constant_n64(sg_list[i].address);
vdma_constant_n( sg_list[i].vdma_xfer_ctl);
vdma_constant_n( sg_list[i].vdma_xfer_rpt);
}
data_address = program_address; //Save back the current data address
vdma_org(tmp_address); //Restore the program address
}
//***********************************************************************************************
//***********************************************************************************************
//**
//** Name: simple.c
//**
//** Description: This is an example test source code used to drive the Lambo TestBench.
//**
//***********************************************************************************************
//***********************************************************************************************
#include "lib/maketest.c"
#define BAR0_BASE 0xFF00000010000000ll
#define BAR1_BASE 0xFF000000A0000000ll
#define BFM_BAR0_BASE 0x8765432120000000ll
#define BFM_BAR1_BASE 0xBB00000040000000ll
//***********************************************************************************************
//**
//** Main:
//**
//** Edit the program below to create your own test script.
//**
//***********************************************************************************************
main(argc,argv)
int argc;
char *argv[];
{
//-----------------------------------------------------------------------------------------------
// Always call maketest_init at the beginning of a test program
//-----------------------------------------------------------------------------------------------
maketest_init(argc,argv);
//================================================================================================
//== START of user script
//================================================================================================
comment("-----------------------------------------------------------------------------");
comment("Generated from: simple.c - do not edit the vec file directly as it is not the source!");
comment("Short example of using the lambo TestBench");
comment("-----------------------------------------------------------------------------");
comment("Select the GN4124 Primary BFM");
model(0);
comment("Initialize the BFM to its default state");
init();
comment("\nDrive reset to the FPGA");
reset(16);
comment("\n");
comment("-----------------------------------------------------------------------------");
comment("Initialize the Primary GN412x BFM model");
comment("-----------------------------------------------------------------------------");
comment("These address ranges will generate traffic from the BFM to the FPGA");
comment("bar BAR ADDR SIZE VC TC S");
bar(0, BAR0_BASE, 0x08000000, 0, 7, 0);
bar(1, BAR1_BASE, 0x10000000, 1, 5, 0);
comment("\nThis allocates a RAM block inside the BFM for the FPGA to access");
comment("bfm_bar BAR ADDR SIZE");
bfm_bar(0, BFM_BAR0_BASE, 0x20000000);
bfm_bar(1, BFM_BAR1_BASE, 0x20000000);
comment("\nWait until the FPGA is un-reset and ready for traffic on the local bus");
wait(64);
comment("\n-----------------------------------------------------------------------------");
comment("Access the descriptor memory in the Lambo design");
comment("-----------------------------------------------------------------------------");
comment("the following three writes will go out in a single packet");
wrb(BAR0_BASE+0x4000, 0xF, 0x87654321);
wrb(BAR0_BASE+0x4004, 0xF, 0xFEEDFACE);
wr( BAR0_BASE+0x4008, 0xF, 0xDEADBEEF);
comment("\nNow read back what was just written");
comment("the following three reads will go out as a single request");
rdb(BAR0_BASE+0x4000, 0xF, 0x87654321, 0xFFFFFFFF);
rdb(BAR0_BASE+0x4004, 0xF, 0xFEEDFACE, 0xFFFFFFFF);
rd( BAR0_BASE+0x4008, 0xF, 0xDEADBEEF, 0xFFFFFFFF);
comment("\n");
flush(256);
comment("\n");
wait(16);
comment("\n");
sync();
//================================================================================================
//== END of user script
//================================================================================================
exit(0);
}
//***********************************************************************************************
//***********************************************************************************************
//**
//** Name: sg_dma.c
//**
//** Description: This runs a scatter/gather DMA scenario for the Lambo TestBench.
//**
//**
//***********************************************************************************************
//***********************************************************************************************
//===============================================================================================
// This provides the framework for creating tests for the testbench as described in
// GN412x Simulation Test Bench User Guide
//===============================================================================================
#include "lib/maketest.c"
//===============================================================================================
// This provides the framework for creating microcode for the 3 or 4DW list type described in
// the application note: "Implementing Multi-channel DMA with the GN412x IP"
//===============================================================================================
#include "lib/vdma_service.c"
//===============================================================================================
// lambo.h contains the address map for the Lambo project
//===============================================================================================
#include "lambo.h"
//===============================================================================================
// Define the Memory Map for the Simulation
//===============================================================================================
#define BAR0_BASE 0xFF00000010000000ll
#define BAR1_BASE 0xFF000000A0000000ll
#define BFM_BAR0_BASE 0x8765432120000000ll
#define BFM_BAR1_BASE 0xBB00000040000000ll
#define CHAN0_DESC_LIST_SIZE 4
#define CHAN1_DESC_LIST_SIZE 4
#define L2P_CHAN0_DMA_LENGTH 0x080
#define L2P_CHAN0_XFER_CTL (0x00010000+L2P_CHAN0_DMA_LENGTH)
#define L2P_CHAN1_DMA_LENGTH 0x080
#define L2P_CHAN1_XFER_CTL (0x00080000+L2P_CHAN1_DMA_LENGTH)
//===============================================================================================
// Define the Memory Map for the Simulation
//===============================================================================================
struct sg_entry_struct sg_list_chan0[] =
{
{ BFM_BAR0_BASE+0x000F0000, L2P_CHAN0_XFER_CTL, 2 },
{ BFM_BAR0_BASE+0x000F1000, L2P_CHAN0_XFER_CTL, 2 },
{ BFM_BAR0_BASE+0x000F2000, L2P_CHAN0_XFER_CTL, 2 },
{ BFM_BAR0_BASE+0x000F3000, L2P_CHAN0_XFER_CTL | 0x80000000, 2 }, //Assert an interrupt
{ BFM_BAR0_BASE+0x000F4000, L2P_CHAN0_XFER_CTL, 2 },
{ BFM_BAR0_BASE+0x000F5000, L2P_CHAN0_XFER_CTL, 2 },
{ BFM_BAR0_BASE+0x000F6000, L2P_CHAN0_XFER_CTL, 2 },
{ BFM_BAR0_BASE+0x000F7000, L2P_CHAN0_XFER_CTL, 2 },
{ 0x0ll, 0, 0 }
};
struct sg_entry_struct sg_list_chan1[] =
{
{ BFM_BAR1_BASE+0x00087000, L2P_CHAN1_XFER_CTL, 1 },
{ BFM_BAR1_BASE+0x00086000, L2P_CHAN1_XFER_CTL, 1 },
{ BFM_BAR1_BASE+0x00085000, L2P_CHAN1_XFER_CTL, 1 },
{ BFM_BAR1_BASE+0x00084000, L2P_CHAN1_XFER_CTL | 0x80000000, 1 }, //Assert an interrupt
{ BFM_BAR1_BASE+0x00083000, L2P_CHAN1_XFER_CTL, 1 },
{ BFM_BAR1_BASE+0x00082000, L2P_CHAN1_XFER_CTL, 1 },
{ BFM_BAR1_BASE+0x00081000, L2P_CHAN1_XFER_CTL, 1 },
{ BFM_BAR1_BASE+0x00080000, L2P_CHAN1_XFER_CTL, 1 },
{ 0x0ll, 0, 0 }
};
//***********************************************************************************************
//**
//** vdma_main: This will insert the DMA microcode and data into the test script
//**
//** The last function call, vdma_process(), will cross reference all of the labels in the
//** source code so that you end up with the proper hexadecimal values that need to be written
//** to descriptor RAM.
//**
//***********************************************************************************************
void vdma_main()
{
vdma_org(0x0000); //This initializes the program address counter
data_address = 0x200; //This initializes the data space address counter
vdma_label("START");
vdma_nop(); //do nothing
//===============================================================================================
// START of the main program loop
//===============================================================================================
// Example source code to be compiled into VDMA binarys or test bench script
vdma_label("MAIN");
vdma_channel_service_4
(
"L2P_CHAN0", //char *base_label, //label to be used for this specific channel
'l', //char direction, //direction='l' for l2p or 'p' for p2l
0, //int event_reg, //The event register bit to be used for interrupt generation
_EXT_COND_0, //int ext_cond, //External condition used for this channel
_EXT_COND_LO, //int condition, //Set to either _EXT_COND_LO or _EXT_COND_HI
1, //int dynamic_list, //set to non zero when the list will be updated dynamicaly
CHAN0_DESC_LIST_SIZE, //int sg_size, //SYS_ADDR step size of list entries that have a repeat count
L2P_CHAN0_DMA_LENGTH, //int sys_addr_increment, //Step size of list entries that have a repeat count
sg_list_chan0 //struct sg_entry_struct *sg_list //SG List itself
);
vdma_channel_service_3
(
"L2P_CHAN1", //char *base_label, //label to be used for this specific channel
'l', //char direction, //direction='l' for l2p or 'p' for p2l
0, //int event_reg, //The event register bit to be used for interrupt generation
_EXT_COND_0, //int ext_cond, //External condition used for this channel
_EXT_COND_LO, //int condition, //Set to either _EXT_COND_LO or _EXT_COND_HI
1, //int dynamic_list, //set to non zero when the list will be updated dynamicaly
CHAN0_DESC_LIST_SIZE, //int sg_size, //SYS_ADDR step size of list entries that have a repeat count
sg_list_chan1 //struct sg_entry_struct *sg_list //SG List itself
);
// vdma_load_rb("MARKER"); //This is to ease debug
// vdma_load_ra("MARKER");
// vdma_load_sys_addr(_IM,"MARKER");
vdma_jmp(_ALWAYS, 0,"MAIN"); //loop forever
//===============================================================================================
// END of the main program loop
//===============================================================================================
//-----------------------------------------------------------------------------------------------
// Global Constants
//-----------------------------------------------------------------------------------------------
vdma_org(0x0100);
vdma_label("ZERO");
vdma_constant_n64(0); //The constant 0
vdma_label("MINUS1");
vdma_constant_n(0xFFFFFFFF); //The constant -1
vdma_label("THREE");
vdma_constant_n(3); //The constant 3
vdma_label("FOUR");
vdma_constant_n(4); //The constant 4
vdma_label("MARKER");
vdma_constant_n64(0x2222222211111111ll);
//===============================================================================================
// Must run vdma_process to resolve the cross-references and generate the memory writes
//===============================================================================================
vdma_process(BAR0_BASE + 0x4000); // This actually printfs the data to the file
}
//***********************************************************************************************
//**
//** Main:
//**
//** Edit the program below to create your own test script.
//**
//***********************************************************************************************
main(argc,argv)
int argc;
char *argv[];
{
int offset=0, i;
//-----------------------------------------------------------------------------------------------
// Always call maketest_init at the beginning of a test program
//-----------------------------------------------------------------------------------------------
maketest_init(argc,argv);
//================================================================================================
//== START of user script
//================================================================================================
comment("-----------------------------------------------------------------------------");
comment("Generated from: simple.c - do not edit the vec file directly as it is not the source!");
comment("Short example of using the lambo TestBench");
comment("-----------------------------------------------------------------------------");
comment("Select the GN4124 Primary BFM");
model(0);
comment("Initialize the BFM to its default state");
init();
comment("\nDrive reset to the FPGA");
reset(16);
comment("\n");
comment("-----------------------------------------------------------------------------");
comment("Initialize the Primary GN412x BFM model");
comment("-----------------------------------------------------------------------------");
comment("These address ranges will generate traffic from the BFM to the FPGA");
comment("bar BAR ADDR SIZE VC TC S");
bar(0, BAR0_BASE, 0x08000000, 0, 7, 0);
bar(1, BAR1_BASE, 0x10000000, 1, 5, 0);
comment("\nThis allocates a RAM block inside the BFM for the FPGA to access");
comment("bfm_bar BAR ADDR SIZE");
bfm_bar(0, BFM_BAR0_BASE, 0x20000000);
bfm_bar(1, BFM_BAR1_BASE, 0x20000000);
comment("\nWait until the FPGA is un-reset and ready for traffic on the local bus");
wait(64);
comment("\n-------------------------------------------------------------------------------");
comment("DO some setup");
comment("-------------------------------------------------------------------------------");
comment("Lambo setup...");
rd(BAR0_BASE + DMA_SEQ_CSR_REG, 0xF, 0x00000000, 0xFFFFFFFF);
flush(0x100);
wr(BAR0_BASE + DMA_SEQ_DPTR_REG, 0xF, 0x0);
wr(BAR0_BASE + DMA_SEQ_EVENT_EN_REG, 0xF, 0x3);
wr(BAR0_BASE + DMA_SEQ_EVENT_CLR_REG, 0xF, 0xFFFFFFFF);
wr(BAR0_BASE + APP_CFG, 0xF, 0x6);
wr(BAR0_BASE + APP_CFG, 0xF, 0x0);
wr(BAR0_BASE + DMA_CFG, 0xF, 0x1F);
wr(BAR0_BASE + DMA_CFG, 0xF, 0x7);
wr(BAR0_BASE + APP_GEN_COUNT, 0xF, 0x0);
wr(BAR0_BASE + APP_RCV_COUNT, 0xF, 0x0);
wr(BAR0_BASE + APP_RCV_ERR_COUNT, 0xF, 0x0);
wr(BAR0_BASE + DMA_PAYLOAD_SIZE, 0xF, 0x8020);
comment("\n-------------------------------------------------------------------------------");
comment("Setup the DMA microcode");
comment("-------------------------------------------------------------------------------");
vdma_main();
comment("\nStart VDMA");
wr(BAR0_BASE + DMA_SEQ_CSR_REG, 0xF, 0x1);
comment("\n-------------------------------------------------------------------------------");
comment("Wait for an Interrupt for Channel 0");
comment("-------------------------------------------------------------------------------");
gpio_wait(2000, 0x0001, 0x0001);
comment("Clear the interrupt");
wr(BAR0_BASE + DMA_SEQ_EVENT_CLR_REG, 0xF, 0x00000001);
//After the interrupt, it is safe to reuse SG list for channel 0
vdma_label_lookup("L2P_CHAN0_LIST", &offset); //This looks up the offset to the SG list for channel 0
printf("-- L2P_CHAN0_LIST=0x%04X which eqates to byte address=0x%08X\n", offset, offset*4);
// for(i=0; i<CHAN0_DESC_LIST_SIZE; i++)
// {
// if(sg_list_chan0[i+4].address == 0) break;
// wrb(BAR0_BASE + 0x4000 + (offset + (i*3))*4, 0xF, (U32) (sg_list_chan0[i+4].address & 0xFFFFFFFF) );
// wrb(BAR0_BASE + 0x4000 + (offset + (i*3))*4 + 4, 0xF, (U32) (sg_list_chan0[i+4].address >> 32) );
// wr( BAR0_BASE + 0x4000 + (offset + (i*3))*4 + 8, 0xF, (U32) sg_list_chan0[i+4].vdma_xfer_ctl );
// }
// wait(100);
comment("\nRead VDMA idle status");
rd(BAR0_BASE + DMA_SEQ_CSR_REG, 0xF, 0x00000000, 0xFFFFFFFF);
flush(256);
wait(16);
wr32(BAR0_BASE + 0x5001, 0x87654321);
wr16(BAR0_BASE + 0x5013, 0x2211);
//================================================================================================
//== END of user script
//================================================================================================
fclose(outfp);
exit(0);
}
//***********************************************************************************************
//***********************************************************************************************
//**
//** Name: simple.c
//**
//** Description: This is an example test source code used to drive the Lambo TestBench.
//**
//***********************************************************************************************
//***********************************************************************************************
#include "lib/maketest.c"
#define BAR0_BASE 0xFF00000010000000ll
#define BAR1_BASE 0xFF000000A0000000ll
#define BFM_BAR0_BASE 0x8765432120000000ll
#define BFM_BAR1_BASE 0xBB00000040000000ll
//***********************************************************************************************
//**
//** Main:
//**
//** Edit the program below to create your own test script.
//**
//***********************************************************************************************
main(argc,argv)
int argc;
char *argv[];
{
//-----------------------------------------------------------------------------------------------
// Always call maketest_init at the beginning of a test program
//-----------------------------------------------------------------------------------------------
maketest_init(argc,argv);
//================================================================================================
//== START of user script
//================================================================================================
comment("-----------------------------------------------------------------------------");
comment("Generated from: simple.c - do not edit the vec file directly as it is not the source!");
comment("Short example of using the lambo TestBench");
comment("-----------------------------------------------------------------------------");
comment("Select the GN4124 Primary BFM");
model(0);
comment("Initialize the BFM to its default state");
init();
comment("\nDrive reset to the FPGA");
reset(16);
comment("\n");
comment("-----------------------------------------------------------------------------");
comment("Initialize the Primary GN412x BFM model");
comment("-----------------------------------------------------------------------------");
comment("These address ranges will generate traffic from the BFM to the FPGA");
comment("bar BAR ADDR SIZE VC TC S");
bar(0, BAR0_BASE, 0x08000000, 0, 7, 0);
bar(1, BAR1_BASE, 0x10000000, 1, 5, 0);
comment("\nThis allocates a RAM block inside the BFM for the FPGA to access");
comment("bfm_bar BAR ADDR SIZE");
bfm_bar(0, BFM_BAR0_BASE, 0x20000000);
bfm_bar(1, BFM_BAR1_BASE, 0x20000000);
comment("\nWait until the FPGA is un-reset and ready for traffic on the local bus");
wait(64);
comment("\n-----------------------------------------------------------------------------");
comment("Access the descriptor memory in the Lambo design");
comment("-----------------------------------------------------------------------------");
comment("the following three writes will go out in a single packet");
wrb(BAR0_BASE+0x4000, 0xF, 0x87654321);
wrb(BAR0_BASE+0x4004, 0xF, 0xFEEDFACE);
wr( BAR0_BASE+0x4008, 0xF, 0xDEADBEEF);
comment("\nNow read back what was just written");
comment("the following three reads will go out as a single request");
rdb(BAR0_BASE+0x4000, 0xF, 0x87654321, 0xFFFFFFFF);
rdb(BAR0_BASE+0x4004, 0xF, 0xFEEDFACE, 0xFFFFFFFF);
rd( BAR0_BASE+0x4008, 0xF, 0xDEADBEEF, 0xFFFFFFFF);
comment("\n");
flush(256);
comment("\n");
wait(16);
comment("\n");
sync();
//================================================================================================
//== END of user script
//================================================================================================
exit(0);
}
-------------------------------------------------------------------------------
-- Generated from: simple.c - do not edit the vec file directly as it is not the source!
-- Short example of using the lambo TestBench
-------------------------------------------------------------------------------
-- Select the GN4124 Primary BFM
model %d0
-- Initialize the BFM to its default state
init
-- Drive reset to the FPGA
reset %d16
-------------------------------------------------------------------------------
-- Initialize the Primary GN412x BFM model
-------------------------------------------------------------------------------
-- These address ranges will generate traffic from the BFM to the FPGA
-- bar BAR ADDR SIZE VC TC S
bar 0 FF00000010000000 08000000 0 7 0
bar 1 FF000000A0000000 10000000 1 5 0
-- This allocates a RAM block inside the BFM for the FPGA to access
-- bfm_bar BAR ADDR SIZE
bfm_bar 0 8765432120000000 20000000
bfm_bar 1 BB00000040000000 20000000
-- Wait until the FPGA is un-reset and ready for traffic on the local bus
wait %d64
-------------------------------------------------------------------------------
-- Access the descriptor memory in the Lambo design
-------------------------------------------------------------------------------
-- the following three writes will go out in a single packet
wrb FF00000010004000 F 87654321
wrb FF00000010004004 F FEEDFACE
wr FF00000010004008 F DEADBEEF
-- Now read back what was just written
-- the following three reads will go out as a single request
rdb FF00000010004000 F 87654321 FFFFFFFF
rdb FF00000010004004 F FEEDFACE FFFFFFFF
rd FF00000010004008 F DEADBEEF FFFFFFFF
flush %d256
wait %d16
sync
//***********************************************************************************************
//***********************************************************************************************
//**
//** Name: simple_dma.c
//**
//** Description: This is an example test source code used to drive the Lambo TestBench.
//**
//**
//***********************************************************************************************
//***********************************************************************************************
#include "lib/maketest.c" //This inserts the Test_Builder C framework
#include "lambo.h" //This is for the project specific registers
//===============================================================================================
// Define the Memory Map for the Simulation
//===============================================================================================
#define BAR0_BASE 0xFF00000010000000ll //rd/wr here generate LB cycles
#define BAR1_BASE 0xFF000000A0000000ll
#define BFM_BAR0_BASE 0x8765432120000000ll //rd/wr here accesses internal BFM memory
#define BFM_BAR1_BASE 0xBB00000040000000ll
#define VDMA_DRAM_BASE (BAR0_BASE + 0x4000ll) //This is where the microcode will be written
//***********************************************************************************************
//**
//** VDMA Sequencer Microcode:
//**
//** The following microcode will get compiled and converted into a series of write cycles
//** so that the BFM will write the microcode into descriptor memory. The last function call
//** vdma_process() will cross reference all of the labels in the source code so that you
//** end up with the proper hexadecimal values that need to be written to descriptor RAM.
//**
//***********************************************************************************************
void vdma_main()
{
//===============================================================================================
// START of the main program loop
//===============================================================================================
// Example source code to be compiled into VDMA binarys or test bench script
vdma_org(0x0000);
vdma_label("MAIN");
vdma_nop();
vdma_label("DO_L2P0");
vdma_load_sys_addr(_IM,"L2P0_SYS_ADDR"); //Load system address from SG entry
vdma_load_xfer_ctl(_IM,"L2P0_XFER_CTL"); //Start DMA0
vdma_label("DO_L2P1");
vdma_load_sys_addr(_IM,"L2P1_SYS_ADDR"); //Load system address from SG entry
vdma_load_xfer_ctl(_IM,"L2P1_XFER_CTL"); //Start DMA1
vdma_label("WAIT4IDLE");
vdma_jmp(_EXT_COND_LO,_LDM_IDLE,"WAIT4IDLE"); //Loop until DMA idle
vdma_sig_event(0, 1, 0x0001);
vdma_label("FOREVER");
vdma_nop();
vdma_jmp(_ALWAYS, 0,"FOREVER"); //Loop forever
//===============================================================================================
// END of the main program loop
//===============================================================================================
//
//-----------------------------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------------------------
vdma_org(0x0100);
vdma_label("L2P0_SYS_ADDR");
vdma_constant_n64(BFM_BAR0_BASE+0x200); //L2P0 system address low/hi
vdma_label("L2P0_XFER_CTL");
vdma_constant_n(0x00010080); //L2P0 transfer control: 128B, STREAM_ID=1
vdma_label("L2P1_SYS_ADDR");
vdma_constant_n64(BFM_BAR1_BASE+0x200); //L2P1 system address low/hi
vdma_label("L2P1_XFER_CTL");
vdma_constant_n(0x00040080); //L2P1 transfer control: 128B, STREAM_ID=4
//===============================================================================================
// Must run vdma_process to resolve the cross-references and generate the memory writes
//===============================================================================================
vdma_process(VDMA_DRAM_BASE); // This actually printfs the data to the file
}
//***********************************************************************************************
//**
//** Main:
//**
//** Edit the program below to create your own test script.
//**
//***********************************************************************************************
main(argc,argv)
int argc;
char *argv[];
{
//-----------------------------------------------------------------------------------------------
// Always call maketest_init at the beginning of a test program
//-----------------------------------------------------------------------------------------------
maketest_init(argc,argv);
//================================================================================================
//== START of user script
//================================================================================================
comment("-----------------------------------------------------------------------------");
comment("Generated from: simple.c - do not edit the vec file directly as it is not the source!");
comment("Short example of using the lambo TestBench");
comment("-----------------------------------------------------------------------------");
comment("Select the GN4124 Primary BFM");
model(0);
comment("Initialize the BFM to its default state");
init();
comment("\nDrive reset to the FPGA");
reset(16);
comment("\n");
comment("-----------------------------------------------------------------------------");
comment("Initialize the Primary GN412x BFM model");
comment("-----------------------------------------------------------------------------");
comment("These address ranges will generate traffic from the BFM to the FPGA");
comment("bar BAR ADDR SIZE VC TC S");
bar(0, BAR0_BASE, 0x08000000, 0, 7, 0);
bar(1, BAR1_BASE, 0x10000000, 1, 5, 0);
comment("\nThis allocates a RAM block inside the BFM for the FPGA to access");
comment("bfm_bar BAR ADDR SIZE");
bfm_bar(0, BFM_BAR0_BASE, 0x20000000);
bfm_bar(1, BFM_BAR1_BASE, 0x20000000);
comment("\nWait until the FPGA is un-reset and ready for traffic on the local bus");
wait(64);
comment("\n-------------------------------------------------------------------------------");
comment("DO some setup");
comment("-------------------------------------------------------------------------------");
comment("Lambo setup...");
rd(BAR0_BASE + DMA_SEQ_CSR_REG, 0xF, 0x00000000, 0xFFFFFFFF);
flush(0x100);
wr(BAR0_BASE + DMA_SEQ_DPTR_REG, 0xF, 0x0);
wr(BAR0_BASE + DMA_SEQ_EVENT_EN_REG, 0xF, 0x1);
wr(BAR0_BASE + DMA_SEQ_EVENT_CLR_REG, 0xF, 0xFFFFFFFF);
wr(BAR0_BASE + APP_CFG, 0xF, 0x6);
wr(BAR0_BASE + APP_CFG, 0xF, 0x0);
wr(BAR0_BASE + DMA_CFG, 0xF, 0x1F);
wr(BAR0_BASE + DMA_CFG, 0xF, 0x7);
wr(BAR0_BASE + APP_GEN_COUNT, 0xF, 0x0);
wr(BAR0_BASE + APP_RCV_COUNT, 0xF, 0x0);
wr(BAR0_BASE + APP_RCV_ERR_COUNT, 0xF, 0x0);
wr(BAR0_BASE + DMA_PAYLOAD_SIZE, 0xF, 0x8020);
comment("\n-------------------------------------------------------------------------------");
comment("Setup the DMA microcode");
comment("-------------------------------------------------------------------------------");
vdma_main();
comment("\nStart VDMA");
wr(BAR0_BASE + DMA_SEQ_CSR_REG, 0xF, 0x1);
gpio_wait(300, 0x0001, 0x0001);
comment("\nRead VDMA idle status");
rd(BAR0_BASE + DMA_SEQ_CSR_REG, 0xF, 0x00000000, 0xFFFFFFFF);
flush(256);
wait(16);
//================================================================================================
//== END of user script
//================================================================================================
fclose(outfp);
exit(0);
}
0x0000 0x00000000 MAIN: vdma_nop()
0x0001 0x40000100 DO_L2P0: vdma_load_sys_addr(r=_IM, "L2P0_SYS_ADDR")
0x0002 0xF0000102 vdma_load_xfer_ctl(_IM, "L2P0_XFER_CTL")
0x0003 0x40000103 DO_L2P1: vdma_load_sys_addr(r=_IM, "L2P1_SYS_ADDR")
0x0004 0xF0000105 vdma_load_xfer_ctl(_IM, "L2P1_XFER_CTL")
0x0005 0x17210005 WAIT4IDLE: vdma_jmp(c=_EXT_COND_LO, ext_cond=_LDM_IDLE, "WAIT4IDLE")
0x0006 0x84000001 vdma_sig_event(s=0, a=1, event_en=0x0001)
0x0007 0x00000000 FOREVER: vdma_nop()
0x0008 0x1A000007 vdma_jmp(c=_ALWAYS, ext_cond=NA, "FOREVER")
0x0100 0x20000200 L2P0_SYS_ADDR: vdma_constant_n64(0x8765432120000200)
0x0101 0x87654321 // vdma_constant_n64 - upper data
0x0102 0x00010080 L2P0_XFER_CTL: vdma_constant_n(0x00010080)
0x0103 0x40000200 L2P1_SYS_ADDR: vdma_constant_n64(0xBB00000040000200)
0x0104 0xBB000000 // vdma_constant_n64 - upper data
0x0105 0x00040080 L2P1_XFER_CTL: vdma_constant_n(0x00040080)
// Label Listing:
// 0x0000 : "MAIN"
// 0x0001 : "DO_L2P0"
// 0x0003 : "DO_L2P1"
// 0x0005 : "WAIT4IDLE"
// 0x0007 : "FOREVER"
// 0x0100 : "L2P0_SYS_ADDR"
// 0x0102 : "L2P0_XFER_CTL"
// 0x0103 : "L2P1_SYS_ADDR"
// 0x0105 : "L2P1_XFER_CTL"
TESTBENCH = testbench
DDRMODEL = sim_models/2048Mb_ddr3
SPEC = ../rtl
GNCORE = ../../../../GN4124_core/hdl/gn4124core/rtl
GNCORE_IP = ../../../../GN4124_core/hdl/spec/ip_cores
DDRCORE = ../../../../ddr3_ctrl_core/hdl/rtl
DDRCORE_IP = ../../../../ddr3_ctrl_core/hdl/spec/ip_cores/ddr_ctrl_bank3/user_design/rtl
# These are the technology specific files
#GLBL = unisims
#FPGA = unisims
VHDL_LIB = testbench
MK = mk
# Change VCOM and VLOG for use with other simulation tools
VCOM = vcom
VLOG = vlog
TOUCH = echo "" > $@
spec : $(MK)/tb_spec.mk
bfm : $(MK)/tb_gn412x.mk
clean :
rm -f $(MK)/*.mk
vdel -lib work -all
vlib work
##################################################################################################
# SPEC Test Bench Project
##################################################################################################
$(MK)/tb_spec.mk : $(TESTBENCH)/tb_spec.vhd $(MK)/spec_ddr_test.mk $(MK)/gn412x_bfm.mk $(MK)/cmd_router.mk \
$(MK)/ddr3.mk
$(VCOM) $(TESTBENCH)/tb_spec.vhd
$(TOUCH)
##################################################################################################
# SPEC Project
##################################################################################################
$(MK)/spec_ddr_test.mk : $(SPEC)/spec_ddr_test.vhd $(MK)/gn4124_core.mk \
$(MK)/gpio_regs.mk $(MK)/ddr3_ctrl.mk
$(VCOM) $(SPEC)/spec_ddr_test.vhd
$(TOUCH)
$(MK)/gpio_regs.mk : $(SPEC)/gpio_regs.vhd
$(VCOM) $(SPEC)/gpio_regs.vhd
$(TOUCH)
# GN4124 core
$(MK)/gn4124_core.mk : $(GNCORE)/spartan6/gn4124_core.vhd $(MK)/gn4124_core_pkg.mk $(MK)/p2l_des.mk \
$(MK)/p2l_decode32.mk $(MK)/wbmaster32.mk $(MK)/l2p_arbiter.mk $(MK)/l2p_ser.mk \
$(MK)/dma_controller.mk $(MK)/l2p_dma_master.mk $(MK)/p2l_dma_master.mk \
$(MK)/serdes_1_to_n_clk_pll_s2_diff.mk
$(VCOM) $(GNCORE)/spartan6/gn4124_core.vhd
$(TOUCH)
$(MK)/gn4124_core_pkg.mk : $(GNCORE)/spartan6/gn4124_core_pkg.vhd
$(VCOM) $(GNCORE)/spartan6/gn4124_core_pkg.vhd
$(TOUCH)
$(MK)/p2l_des.mk : $(GNCORE)/spartan6/p2l_des.vhd $(MK)/serdes_1_to_n_data_s2_se.mk
$(VCOM) $(GNCORE)/spartan6/p2l_des.vhd
$(TOUCH)
$(MK)/p2l_decode32.mk : $(GNCORE)/p2l_decode32.vhd
$(VCOM) $(GNCORE)/p2l_decode32.vhd
$(TOUCH)
$(MK)/wbmaster32.mk : $(GNCORE)/wbmaster32.vhd $(MK)/fifo_32x512.mk $(MK)/fifo_64x512.mk
$(VCOM) $(GNCORE)/wbmaster32.vhd
$(TOUCH)
$(MK)/l2p_arbiter.mk : $(GNCORE)/l2p_arbiter.vhd
$(VCOM) $(GNCORE)/l2p_arbiter.vhd
$(TOUCH)
$(MK)/dma_controller.mk : $(GNCORE)/dma_controller.vhd $(MK)/dma_controller_wb_slave.mk
$(VCOM) $(GNCORE)/dma_controller.vhd
$(TOUCH)
$(MK)/l2p_dma_master.mk : $(GNCORE)/l2p_dma_master.vhd $(MK)/fifo_32x512.mk
$(VCOM) $(GNCORE)/l2p_dma_master.vhd
$(TOUCH)
$(MK)/p2l_dma_master.mk : $(GNCORE)/p2l_dma_master.vhd $(MK)/fifo_64x512.mk
$(VCOM) $(GNCORE)/p2l_dma_master.vhd
$(TOUCH)
$(MK)/dma_controller_wb_slave.mk : $(GNCORE)/dma_controller_wb_slave.vhd
$(VCOM) $(GNCORE)/dma_controller_wb_slave.vhd
$(TOUCH)
$(MK)/l2p_ser.mk : $(GNCORE)/spartan6/l2p_ser.vhd $(MK)/serdes_n_to_1_s2_se.mk \
$(MK)/serdes_n_to_1_s2_diff.mk
$(VCOM) $(GNCORE)/spartan6/l2p_ser.vhd
$(TOUCH)
$(MK)/serdes_1_to_n_clk_pll_s2_diff.mk : $(GNCORE)/spartan6/serdes_1_to_n_clk_pll_s2_diff.vhd
$(VCOM) $(GNCORE)/spartan6/serdes_1_to_n_clk_pll_s2_diff.vhd
$(TOUCH)
$(MK)/serdes_1_to_n_data_s2_se.mk : $(GNCORE)/spartan6/serdes_1_to_n_data_s2_se.vhd
$(VCOM) $(GNCORE)/spartan6/serdes_1_to_n_data_s2_se.vhd
$(TOUCH)
$(MK)/serdes_n_to_1_s2_se.mk : $(GNCORE)/spartan6/serdes_n_to_1_s2_se.vhd
$(VCOM) $(GNCORE)/spartan6/serdes_n_to_1_s2_se.vhd
$(TOUCH)
$(MK)/serdes_n_to_1_s2_diff.mk : $(GNCORE)/spartan6/serdes_n_to_1_s2_diff.vhd
$(VCOM) $(GNCORE)/spartan6/serdes_n_to_1_s2_diff.vhd
$(TOUCH)
$(MK)/fifo_32x512.mk : $(GNCORE_IP)/fifo_32x512.vhd
$(VCOM) $(GNCORE_IP)/fifo_32x512.vhd
$(TOUCH)
$(MK)/fifo_64x512.mk : $(GNCORE_IP)/fifo_64x512.vhd
$(VCOM) $(GNCORE_IP)/fifo_64x512.vhd
$(TOUCH)
# DDR3 core
$(MK)/ddr3_ctrl.mk : $(DDRCORE)/ddr3_ctrl.vhd $(MK)/ddr3_ctrl_wb.mk $(MK)/ddr3_ctrl_wrapper.mk
$(VCOM) $(DDRCORE)/ddr3_ctrl.vhd
$(TOUCH)
$(MK)/ddr3_ctrl_wb.mk : $(DDRCORE)/ddr3_ctrl_wb.vhd
$(VCOM) $(DDRCORE)/ddr3_ctrl_wb.vhd
$(TOUCH)
$(MK)/ddr3_ctrl_wrapper.mk : $(DDRCORE)/../spec/rtl/ddr3_ctrl_wrapper.vhd $(MK)/ddr_ctrl_bank3.mk
$(VCOM) $(DDRCORE)/../spec/rtl/ddr3_ctrl_wrapper.vhd
$(TOUCH)
$(MK)/ddr_ctrl_bank3.mk : $(DDRCORE_IP)/ddr_ctrl_bank3.vhd $(MK)/memc3_infrastructure.mk $(MK)/memc3_wrapper.mk
$(VCOM) $(DDRCORE_IP)/ddr_ctrl_bank3.vhd
$(TOUCH)
$(MK)/memc3_infrastructure.mk : $(DDRCORE_IP)/memc3_infrastructure.vhd
$(VCOM) $(DDRCORE_IP)/memc3_infrastructure.vhd
$(TOUCH)
$(MK)/memc3_wrapper.mk : $(DDRCORE_IP)/memc3_wrapper.vhd $(MK)/mcb_raw_wrapper.mk
$(VCOM) $(DDRCORE_IP)/memc3_wrapper.vhd
$(TOUCH)
$(MK)/mcb_raw_wrapper.mk : $(DDRCORE_IP)/mcb_raw_wrapper.vhd $(MK)/mcb_soft_calibration_top.mk
$(VCOM) $(DDRCORE_IP)/mcb_raw_wrapper.vhd
$(TOUCH)
$(MK)/mcb_soft_calibration_top.mk : $(DDRCORE_IP)/mcb_soft_calibration_top.vhd $(MK)/mcb_soft_calibration.mk
$(VCOM) $(DDRCORE_IP)/mcb_soft_calibration_top.vhd
$(TOUCH)
$(MK)/mcb_soft_calibration.mk : $(DDRCORE_IP)/mcb_soft_calibration.vhd $(MK)/iodrp_controller.mk \
$(MK)/iodrp_mcb_controller.mk
$(VCOM) $(DDRCORE_IP)/mcb_soft_calibration.vhd
$(TOUCH)
$(MK)/iodrp_controller.mk : $(DDRCORE_IP)/iodrp_controller.vhd
$(VCOM) $(DDRCORE_IP)/iodrp_controller.vhd
$(TOUCH)
$(MK)/iodrp_mcb_controller.mk : $(DDRCORE_IP)/iodrp_mcb_controller.vhd
$(VCOM) $(DDRCORE_IP)/iodrp_mcb_controller.vhd
$(TOUCH)
##################################################################################################
# Test Bench Project
##################################################################################################
$(MK)/tb_gn412x.mk : $(TESTBENCH)/tb_gn412x.vhd $(MK)/gn412x_bfm.mk $(MK)/cmd_router.mk
$(VCOM) $(TESTBENCH)/tb_gn412x.vhd
$(TOUCH)
$(MK)/gn412x_bfm.mk : $(TESTBENCH)/gn412x_bfm.vhd $(MK)/textutil.mk $(MK)/mem_model.mk
$(VCOM) $(TESTBENCH)/gn412x_bfm.vhd
$(TOUCH)
$(MK)/mem_model.mk : $(VHDL_LIB)/mem_model.vhd
$(VCOM) -87 $(VHDL_LIB)/mem_model.vhd
$(TOUCH)
$(MK)/textutil.mk : $(VHDL_LIB)/textutil.vhd $(MK)/util.mk
$(VCOM) $(VHDL_LIB)/textutil.vhd
$(TOUCH)
$(MK)/util.mk : $(VHDL_LIB)/util.vhd
$(VCOM) $(VHDL_LIB)/util.vhd
$(TOUCH)
$(MK)/cmd_router.mk : $(TESTBENCH)/cmd_router.vhd $(MK)/cmd_router1.mk $(MK)/textutil.mk
$(VCOM) $(TESTBENCH)/cmd_router.vhd
$(TOUCH)
$(MK)/cmd_router1.mk : $(TESTBENCH)/cmd_router1.vhd $(MK)/textutil.mk
$(VCOM) $(TESTBENCH)/cmd_router1.vhd
$(TOUCH)
# DDR3 model
$(MK)/ddr3.mk : $(DDRMODEL)/ddr3.v
$(VLOG) +incdir+$(DDRMODEL) +define+sg15E +define+x16 $(DDRMODEL)/ddr3.v
$(TOUCH)
-- ***********************************************************************************
-- *** Warning: this file is automatically generated. ***
-- ***********************************************************************************
-- *** Do not edit this file directly as it is not the source! ***
-- ***********************************************************************************
-------------------------------------------------------------------------------
-- Generated from: simple.c - do not edit the vec file directly as it is not the source!
-- Short example of using the lambo TestBench
-------------------------------------------------------------------------------
-- Select the GN4124 Primary BFM
model %d0
-- Initialize the BFM to its default state
init
-- Drive reset to the FPGA
reset %d16
-------------------------------------------------------------------------------
-- Initialize the Primary GN412x BFM model
-------------------------------------------------------------------------------
-- These address ranges will generate traffic from the BFM to the FPGA
-- bar BAR ADDR SIZE VC TC S
bar 0 FF00000000000000 08000000 0 7 0
--bar 1 FF000000A0000000 10000000 1 5 0
-- This allocates a RAM block inside the BFM for the FPGA to access
-- bfm_bar BAR ADDR SIZE
bfm_bar 0 0000000040000000 20000000
bfm_bar 1 0000000020000000 20000000
-- bfm_bar 0 BB00000040000000 20000000
-- bfm_bar 1 00000000123456f8 20000000
-- Wait until the FPGA is un-reset and ready for traffic on the local bus
wait %d64
-------------------------------------------------------------------------------
-- Access the descriptor memory in the Lambo design
-------------------------------------------------------------------------------
-- the following three writes will go out in a single packet
wr 0000000040000000 F C0FFEE82
wr 0000000040000004 F 00000001
wr 0000000040000008 F 00000002
wr 000000004000000C F 00000003
wr 0000000040000010 F 00000004
wr 0000000040000014 F 00000005
wr 0000000040000018 F 00000006
wr 000000004000001C F 00000007
wr 0000000040000020 F 00000008
wr 0000000040000024 F 00000009
wr 0000000040000028 F 0000000A
wr 000000004000002C F 0000000B
wr 0000000040000030 F 0000000C
wr 0000000040000034 F 0000000D
wr 0000000040000038 F 0000000E
wr 000000004000003C F 0000000F
wr 0000000040000040 F 00000010
wr 0000000040000044 F 00000011
wr 0000000040000048 F 00000012
wr 000000004000004C F 00000013
wr 0000000040000050 F 00000014
wr 0000000040000054 F 00000015
wr 0000000040000058 F 00000016
wr 000000004000005C F 00000017
wr 0000000040000060 F 00000018
wr 0000000040000064 F 00000019
wr 0000000040000068 F 0000001A
wr 000000004000006C F 0000001B
wr 0000000040000070 F 0000001C
wr 0000000040000074 F 0000001D
wr 0000000040000078 F 0000001E
wr 000000004000007C F 0000001F
wr 0000000040000080 F 00000020
wr 0000000040000084 F 00000021
wr 0000000040000088 F 00000022
wr 000000004000008C F 00000023
wr 0000000040000090 F 00000024
wr 0000000040000094 F 00000025
wr 0000000040000098 F 00000026
wr 000000004000009C F 00000027
wr 00000000400000A0 F 00000028
wr 00000000400000A4 F 00000029
wr 00000000400000A8 F 0000002A
wr 00000000400000AC F 0000002B
wr 00000000400000B0 F 0000002C
wr 00000000400000B4 F 0000002D
wr 00000000400000B8 F 0000002E
wr 00000000400000BC F 0000002F
wr 00000000400000C0 F 00000030
wr 0000000040000F00 F 00000F00
wr 0000000040000F04 F 00000F01
wr 0000000040000F08 F 00000F02
wr 0000000040000F0C F 00000F03
wr 0000000040000F10 F 00000F04
wr 0000000040000F14 F 00000F05
wr 0000000040000F18 F 00000F06
wr 0000000040000F1C F 00000F07
wr 0000000040000F20 F 00000F08
wr 0000000040000F24 F 00000F09
wr 0000000040000F28 F 00000F0A
wr 0000000040000F2C F 00000F0B
wr 0000000040000F30 F 00000F0C
wr 0000000040000F34 F 00000F0D
wr 0000000040000F38 F 00000F0E
wr 0000000040000F3C F 00000F0F
wr 0000000040000F40 F 00000F10
wr 0000000040000F44 F 00000F11
wr 0000000040000F48 F 00000F12
wr 0000000040000F4C F 00000F13
wr 0000000040000F50 F 00000F14
wr 0000000040000F54 F 00000F15
wr 0000000040000F58 F 00000F16
wr 0000000040000F5C F 00000F17
wr 0000000040000F60 F 00000F18
wr 0000000040000F64 F 00000F19
wr 0000000040000F68 F 00000F1A
wr 0000000040000F6C F 00000F1B
wr 0000000040000F70 F 00000F1C
wr 0000000040000F74 F 00000F1D
wr 0000000040000F78 F 00000F1E
wr 0000000040000F7C F 00000F1F
wr 0000000040000F80 F 00000F20
wr 0000000040000F84 F 00000F21
wr 0000000040000F88 F 00000F22
wr 0000000040000F8C F 00000F23
wr 0000000040000F90 F 00000F24
wr 0000000040000F94 F 00000F25
wr 0000000040000F98 F 00000F26
wr 0000000040000F9C F 00000F27
wr 0000000040000FA0 F 00000F28
wr 0000000040000FA4 F 00000F29
wr 0000000040000FA8 F 00000F2A
wr 0000000040000FAC F 00000F2B
wr 0000000040000FB0 F 00000F2C
wr 0000000040000FB4 F 00000F2D
wr 0000000040000FB8 F 00000F2E
wr 0000000040000FBC F 00000F2F
-- CSR wishbone test
rd FF00000000040000 F DEAD0000 FFFF0000
wr FF0000000008000C F 00000003
rd FF0000000008000C F 00000003 FFFFFFFF
wait %d640
-- DDR access trough CSR wishbone
--wr FF000000000C0004 F DEADC0DE
--wait %d300
--rd FF000000000C0004 F DEADC0DE FFFFFFFF
wait %d300
-- DDR access trough DMA wishbone
wr 0000000020000000 F 00000000
wr 0000000020000004 F 40000000
wr 0000000020000008 F 00000000
-- DMA length
wr 000000002000000C F 00000004
wr 0000000020000010 F 00000000
wr 0000000020000014 F 00000000
wr 0000000020000018 F 00000000
-- wrb FF00000010004004 F 00000000
wr FF00000000000008 F 00000000
wr FF0000000000000C F 40000000
wr FF00000000000010 F 00000000
-- DMA length
wr FF00000000000014 F 00000004
wr FF00000000000018 F 20000000
wr FF0000000000001C F 00000000
wr FF00000000000020 F 00000003
wr FF00000000000000 F 00000001
-- Now read back what was just written
-- the following three reads will go out as a single request
--rdb FF00000010004004 F FEEDFACE FFFFFFFF
--rdb FF00000010004008 F DBDBDBDB FFFFFFFF
--rd FF00000010004008 F DEADBEEF FFFFFFFF
--wrb FF0000001000401C F 00000000
--wrb FF00000010004024 F 00000000
--wr FF00000010004000 F 00000001
--rdb FF00000010004000 F 00000002 FFFFFFFF
--rdb FF00000010004004 F 00000000 FFFFFFFF
--rdb FF00000010004008 F 5A5A5A5A FFFFFFFF
--rdb FF0000001000400C F 12345678 FFFFFFFF
--rdb FF00000010004010 F 00000000 FFFFFFFF
--rdb FF00000010004014 F 00000010 FFFFFFFF
--rdb FF00000010004018 F 00000000 FFFFFFFF
--rdb FF0000001000401C F 00000000 FFFFFFFF
--rd FF00000010004020 F 00000000 FFFFFFFF
wait %d160
--wr FF00000010004000 F 00000001
--rd FF0000001000400C F DEADBEEF FFFFFFFF
--rd FF00000010004008 F ABABABAB FFFFFFFF
wait %d
flush %d256
wait %d16
sync
m255
K3
13
cModel Technology
Z0 d/home/mcattin/projects/GN4124_core/hdl_trunk/spec/sim
Exilinx_dummy_sim
w1311674401
Z1 d/home/mcattin/projects/GN4124_core/hdl_trunk/spec/sim
8../../gn4124core/ip_cores/general-cores/modules/genrams/xilinx/sim_stub/dummy.vhd
F../../gn4124core/ip_cores/general-cores/modules/genrams/xilinx/sim_stub/dummy.vhd
l0
L1
VKd8^[`j@TZDeV[[hfDI:J0
!s100 nF<;LZ6J0iDiIE_]ATjaA3
Z2 OE;C;6.6e_1;45
32
o-quiet -work fifo_generator_v6_1
Z3 tExplicit 1
m255
K3
cModel Technology
File deleted