Forum Discussion
Altera_Forum
Honored Contributor
14 years agoOK, so now I have 3 arrays of data, each containing 100 integers defined in NIOS C code as:
alt_u8 line1 = {1, 2, 3, ..., 100};
alt_u8 line2 = {10, 10, 10, ..., 10};
alt_u8 line3 = {1, 2, 3, ..., 100};
The next step is I want to apply a calculation to these arrays. Imagine these arrays are 3 rows of pixel values and I want to do a Sobel operation on them. I found the following code on the web to do this job:
module sobel_mine( p0, p1, p2, p3, p5, p6, p7, p8, out);
input p0,p1,p2,p3,p5,p6,p7,p8; // 8 bit pixels inputs
output out; // 8 bit output pixel
wire signed gx,gy;
wire signed abs_gx,abs_gy;
wire sum;
assign gx=((p2-p0)+((p5-p3)<<1)+(p8-p6));//sobel mask for gradient in horiz. direction
assign gy=((p0-p6)+((p1-p7)<<1)+(p2-p8));//sobel mask for gradient in vertical direction
assign abs_gx = (gx? ~gx+1 : gx); // to find the absolute value of gx.
assign abs_gy = (gy? ~gy+1 : gy); // to find the absolute value of gy.
assign sum = (abs_gx+abs_gy); // finding the sum
assign out = (|sum)?8'hff : sum; // to limit the max value to 255
endmodule
So to interface this verilog code with NIOSII, I create 8 ouput PIOs of size 8 bits, and declare them in the C code as:
volatile int* data_out_0_ptr = (int *) 0x08208010; // Data_out_0 address
volatile int* data_out_1_ptr = (int *) 0x08208020;// Data_out_1 address
.
.
.
volatile int* data_out_8_ptr = (int *) 0x08208080;// Data_out_8 address
Then I do a for-loop to access each element and send it to the verilog module for the calculation
for( i=0; i<98; i++)
{
*(data_out_0_ptr)= line1;
*(data_out_1_ptr)= line1;
*(data_out_2_ptr)= line1;
*(data_out_3_ptr)= line2;
*(data_out_5_ptr)= line2;
*(data_out_6_ptr)= line3;
*(data_out_7_ptr)= line3;
*(data_out_8_ptr)= line3;
sum_val = *result_back_ptr ;
//printf("sum_val = %d\n", sum_val);
}
This code as it is works fine but I am sure that I am not taking FPGA's advantage. My new queries are: 1) Instead of having 8 ouput PIOs of 8 bits each, can I have 2 ouput PIO of 32 bits? If yes, how do I modify the C code to reference the right address? For example, suppose I have my 32-bit PIO data_out_32bit_ptr at address 0x08208090. In the C code for-loop, I am not sure how to reference the correct data. Is something like below correct?
*(data_out_32bit_ptr)= line1;
*(data_out_32bit_ptr + 0x8)= line1;
*(data_out_32bit_ptr + 0x10)= line1;
*(data_out_32bit_ptr + 0x18)= line2;
But I see the End address as being 0x0820809f in SOPC Builder when I include such a 32-bit ouput PIO. 2) I suppose I can make the most of FPGA parallelism by getting rid of this for-loop. But how do I send the data then? 3) Also, the results contain 98 values which I can print on the console window. But I need to store the values. I tried the altera_hostfs and I managed to send the data to a text file on my computer (after 3 days of fighting ;)!) But this works only when I choose Debug As -> NIOS II Hardware and it seems to run slower than when I choose Run As -> NIOS II Hardware. What is the best way to get those values?