Forum Discussion
Altera_Forum
Honored Contributor
14 years agoI have tested a small verilog script that does a Sobel edge detection (see attached folder - Sobel_DE2_Cam.v and a few Megawizard generated files) by running it on a video stream coming from a camera attached to my DE2 board, and I can see the edges being picked up on the VGA display. SOPC Builder and NIOS SBT were not involved at all.
But now instead of using the camera, I want to do the same operation on a single image which I will read from my host computer and store in the SDRAM of the DE2 board. So I tried to make an SOPC Peripheral out of the verilog file to make use of DMA controllers as suggested by many forum members. Currently, apart from clk and reset, I have all of them as avalon slave with the following signal types: in_valid - write in_data - writedata out_data - readdata Are these signal type assignments correct? Now to be able to use it with DMA controllers, what other slave signals do I need? I saw in other examples that 'address' and 'chipselect' signals are needed. But I don't know how to use them within my code! Can someone please help me modify that Sobel_DE2_Cam to a 'DMA friendly' one to be used with one single frame of data? I've been pulling my hairs with this task for many weeks now! I badly need help. I then intend to slot that component between two DMA controllers, and use C code along these lines below in NIOS SBT to do the processing.# define ROW 480# define COL 640# define IMAGE_BUF_BYTES ROW * COL # define LOAD_DMA_BASE DMA_1_BASE# define STORE_DMA_BASE DMA_2_BASE# define FILTER_BASE SOBEL_DE2_BASE
// -- Set up the buffers
tx_buf = (alt_u8 *)malloc(IMAGE_BUF_BYTES);
rx_buf = (alt_u8 *)malloc(IMAGE_BUF_BYTES);
//Read image from computer and assign to tx_buf
run_filter(tx_buf, rx_buf); // Do the Processing with DMA controller taking charge
//--------- functions to be used to do DMA transfer
void run_filter(alt_u8* tx_buf, alt_u8* rx_buf)
{
load_filter(tx_buf);
store_filter(rx_buf);
while ((IORD_ALTERA_AVALON_DMA_STATUS (LOAD_DMA_BASE) & ALTERA_AVALON_DMA_STATUS_DONE_MSK) != ALTERA_AVALON_DMA_STATUS_DONE_MSK)
{
//printf("\n In 1st loop");
}
while ((IORD_ALTERA_AVALON_DMA_STATUS (STORE_DMA_BASE) & ALTERA_AVALON_DMA_STATUS_DONE_MSK) != ALTERA_AVALON_DMA_STATUS_DONE_MSK)
{
// printf("\n In 2nd loop");
}
}
void load_filter(alt_u8* tx_buf)
{
// Clear any pending interrupts
IOWR_ALTERA_AVALON_DMA_CONTROL (LOAD_DMA_BASE, 0);
IOWR_ALTERA_AVALON_DMA_STATUS (LOAD_DMA_BASE, 0);
IOWR_ALTERA_AVALON_DMA_RADDRESS (LOAD_DMA_BASE, tx_buf);
IOWR_ALTERA_AVALON_DMA_WADDRESS (LOAD_DMA_BASE, FILTER_BASE);
IOWR_ALTERA_AVALON_DMA_LENGTH (LOAD_DMA_BASE, IMAGE_BUF_BYTES);
IOWR_ALTERA_AVALON_DMA_CONTROL (LOAD_DMA_BASE,ALTERA_AVALON_DMA_CONTROL_WCON_MSK |ALTERA_AVALON_DMA_CONTROL_GO_MSK |ALTERA_AVALON_DMA_CONTROL_LEEN_MSK |ALTERA_AVALON_DMA_CONTROL_WORD_MSK);
}
void store_filter(alt_u8* rx_buf)
{
// Clear any pending interrupts
IOWR_ALTERA_AVALON_DMA_CONTROL (STORE_DMA_BASE, 0);
IOWR_ALTERA_AVALON_DMA_STATUS (STORE_DMA_BASE, 0);
IOWR_ALTERA_AVALON_DMA_RADDRESS (STORE_DMA_BASE, FILTER_BASE);
IOWR_ALTERA_AVALON_DMA_WADDRESS (STORE_DMA_BASE, rx_buf );
IOWR_ALTERA_AVALON_DMA_LENGTH (STORE_DMA_BASE, IMAGE_BUF_BYTES);
IOWR_ALTERA_AVALON_DMA_CONTROL (STORE_DMA_BASE,ALTERA_AVALON_DMA_CONTROL_RCON_MSK |ALTERA_AVALON_DMA_CONTROL_GO_MSK | ALTERA_AVALON_DMA_CONTROL_LEEN_MSK |ALTERA_AVALON_DMA_CONTROL_WORD_MSK);
}