IMG_HW.C


 /*************************************************************************** * * img_hw.c - Image Convolution Hardware Processes * * Copyright (c) 2004 by Green Mountain Computing Systems, Inc. * All rights reserved. *  ***************************************************************************/ #include <stdio.h> #include "co.h" #include "cosim_log.h" #include "img.h" extern void call_fpga(co_memory imgmem, co_signal start, co_signal end); void to_stream(co_signal go, co_memory imgmem, co_stream output_stream) {    int16 i, j;   uint32 offset, data, d0;   uint32 row[IMG_WIDTH / 2];   IF_SIM(cosim_logwindow log;)   IF_SIM(log = cosim_logwindow_create("to_stream");)   co_signal_wait(go, &data);   co_stream_open(output_stream, O_WRONLY, INT_TYPE(32));   offset = 0;   for ( i = 0; i < IMG_HEIGHT; i++ ) {             co_memory_readblock(imgmem, offset, row, IMG_WIDTH * sizeof(int16));            for ( j = 0; j < (IMG_WIDTH / 2); j++ ) { #pragma CO PIPELINE             d0 = row[j];             data  = ((d0 >> 8) & 0xf8) << 16;             data |= ((d0 >> 3) & 0xf8) << 8;             data |= (d0 << 2) & 0xfc;             co_stream_write(output_stream, &data, sizeof(int32));          d0 = d0 >> 16;             data  = ((d0 >> 8) & 0xf8) << 16;             data |= ((d0 >> 3) & 0xf8) << 8;             data |= (d0 << 2) & 0xfc;             co_stream_write(output_stream, &data, sizeof(int32));        }        offset += IMG_WIDTH * sizeof(int16);   }   data = 0;   co_stream_write(output_stream, &data, sizeof(int32));   co_stream_write(output_stream, &data, sizeof(int32));   co_stream_close(output_stream); } /* The following process generates a marching three-pixel column in 3 separate    output streams from the single input stream.  This process can be used    to feed pixels to any marching cubes image processing algorithm using a 3x3    kernel.  It can easily be extended for other kernel sizes.  For example,    given a 5x5 image with the input stream:     0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25    this process will generate:      0  1  2  3  4   5  6  7  8  9   10 11 12 13 14      5  6  7  8  9   10 11 12 13 14  15 16 17 18 19      10 11 12 13 14  15 16 17 18 19  20 21 22 23 24    This process generates 3-pixel columns every 2 cycles. */ void prep_run(co_stream input_stream, co_stream r0, co_stream r1, co_stream r2) {     int32 i, j;    int32 B[IMG_WIDTH], C[IMG_WIDTH];    int32 A01, A02, p02, p12, p22;     IF_SIM(cosim_logwindow log;)     IF_SIM(log = cosim_logwindow_create("prep_run");)     co_stream_open(input_stream, O_RDONLY, INT_TYPE(32));     co_stream_open(r0, O_WRONLY, INT_TYPE(32));     co_stream_open(r1, O_WRONLY, INT_TYPE(32));     co_stream_open(r2, O_WRONLY, INT_TYPE(32));     co_stream_read(input_stream, &A01, sizeof(int32));     co_stream_read(input_stream, &A02, sizeof(int32));     for ( j = 0; j < IMG_WIDTH; j++ )              co_stream_read(input_stream, &B[j], sizeof(int32));     for ( j = 0; j < IMG_WIDTH; j++ )         co_stream_read(input_stream, &C[j], sizeof(int32));     co_stream_write(r0, &A01, sizeof(int32));     co_stream_write(r1, &B[IMG_WIDTH - 2], sizeof(int32));     co_stream_write(r2, &C[IMG_WIDTH - 2], sizeof(int32));     co_stream_write(r0, &A02, sizeof(int32));     co_stream_write(r1, &B[IMG_WIDTH - 1], sizeof(int32));     co_stream_write(r2, &C[IMG_WIDTH - 1], sizeof(int32));     for ( i = 2; i < IMG_HEIGHT; i++ ) {             j = 0;            do {                     p02 = B[j];                    p12 = C[j];                    co_stream_read(input_stream, &p22, sizeof(int32));                    co_stream_write(r0, &p02, sizeof(int32));                    co_stream_write(r1, &p12, sizeof(int32));                    co_stream_write(r2, &p22, sizeof(int32));                    B[j] = p12;                    C[j] = p22;                    j++;            }  while ( j < IMG_WIDTH );    }    co_stream_close(input_stream);    co_stream_close(r0);    co_stream_close(r1);    co_stream_close(r2); }  #define RED(rgb) ((uint8)((rgb) >> 16)) #define GREEN(rgb) ((uint8)((rgb) >> 8)) #define BLUE(rgb) ((uint8)(rgb)) /* This process inputs a marching column of pixels from the prep_run process and    applies a 3x3 convolution to the image to produce an output image on the output     stream.  A pipeline is utilized to generate one output pixel every two cycles.    This particular convolution performs edge detection on the image. */ void filter_run(co_stream r0, co_stream r1, co_stream r2, co_stream output_stream) {    uint32 data,res;   uint32 p00, p01, p02, p10, p11, p12, p20, p21, p22;   uint16 d0;   IF_SIM(cosim_logwindow log;)   IF_SIM(log = cosim_logwindow_create("filter_run");)   co_stream_open(r0, O_RDONLY, INT_TYPE(32));   co_stream_open(r1, O_RDONLY, INT_TYPE(32));   co_stream_open(r2, O_RDONLY, INT_TYPE(32));   co_stream_open(output_stream, O_WRONLY, INT_TYPE(32));   p00 = 0; p01 = 0; p02 = 0;   p10 = 0; p11 = 0; p12 = 0;   p20 = 0; p21 = 0; p22 = 0;   while ( co_stream_read(r0, &data, sizeof(int32)) == co_err_none ) {  #pragma CO PIPELINE #pragma CO set stageDelay 256     p00 = p01; p01 = p02;     p10 = p11; p11 = p12;     p20 = p21; p21 = p22;     p02 = data;     co_stream_read(r1, &p12, sizeof(int32));     co_stream_read(r2, &p22, sizeof(int32));     d0 = RED(p11) << 3;     d0 = d0 - RED(p00);     d0 = d0 - RED(p01);     d0 = d0 - RED(p02);     d0 = d0 - RED(p10);     d0 = d0 - RED(p12);     d0 = d0 - RED(p20);     d0 = d0 - RED(p21);     d0 = d0 - RED(p22);     d0 &= (d0 >> 15) - 1;     res = d0 & 0xff;     d0 = GREEN(p11) << 3;     d0 = d0 - GREEN(p00);     d0 = d0 - GREEN(p01);     d0 = d0 - GREEN(p02);     d0 = d0 - GREEN(p10);     d0 = d0 - GREEN(p12);     d0 = d0 - GREEN(p20);     d0 = d0 - GREEN(p21);     d0 = d0 - GREEN(p22);     d0 &= (d0 >> 15) - 1;     res = (res << 8) | (d0 & 0xff);     d0 = BLUE(p11) << 3;     d0 = d0 - BLUE(p00);     d0 = d0 - BLUE(p01);     d0 = d0 - BLUE(p02);     d0 = d0 - BLUE(p10);     d0 = d0 - BLUE(p12);     d0 = d0 - BLUE(p20);     d0 = d0 - BLUE(p21);     d0 = d0 - BLUE(p22);     d0 &= (d0 >> 15) - 1;     res = (res << 8) | (d0 & 0xff);     co_stream_write(output_stream, &res, sizeof(int32));   }    co_stream_close(r0);   co_stream_close(r1);   co_stream_close(r2);   co_stream_close(output_stream); }  void from_stream(co_stream input_stream, co_memory imgmem, co_signal done) {    uint8 err;   int16 i;   int32 offset, low, data, d0;   int32 rowout[IMG_WIDTH / 2];    IF_SIM(cosim_logwindow log;)    IF_SIM(log = cosim_logwindow_create("from_stream");)    co_stream_open(input_stream, O_RDONLY, INT_TYPE(32));    offset = 0;    do {            for ( i = 0; i < (IMG_WIDTH / 2); i++ ) {   #pragma CO PIPELINE              err = co_stream_read(input_stream, &d0, sizeof(d0));              if ( err != co_err_none ) break;              low = (d0 >> 19) & 0x1f;              low = (low << 5) | ((d0 >> 11) & 0x1f);              low = (low << 6) | ((d0 >>  2) & 0x3f);              err = co_stream_read(input_stream, &d0, sizeof(d0));              if ( err != co_err_none) break;              data = d0 >> 19;              data = (data << 5) | ((d0 >> 11) & 0x1f);              data = (data << 6) | ((d0 >>  2) & 0x3f);              rowout[i] = (data << 16) | low;          }           if ( err != co_err_none) break;          co_memory_writeblock(imgmem, offset, rowout, IMG_WIDTH * sizeof(int16));          offset += IMG_WIDTH * sizeof(int16);  }  while ( 1 );  co_stream_close(input_stream);  co_signal_post(done, 0); } void config_img(void *arg) {    int error;   co_signal startsig, donesig;   co_memory shrmem;   co_stream istream, row0, row1, row2, ostream;   co_process reader, writer;   co_process cpu_proc, prep_proc, filter_proc;   startsig = co_signal_create("start");   donesig  = co_signal_create("done");   shrmem = co_memory_create("image", "heap0",                             IMG_WIDTH * IMG_HEIGHT * sizeof(uint16));   istream = co_stream_create("istream", INT_TYPE(32), IMG_HEIGHT/2);   row0 = co_stream_create("row0",   INT_TYPE(32), 4);   row1= co_stream_create("row1",   INT_TYPE(32), 4);   row2 = co_stream_create("row2",   INT_TYPE(32), 4);   ostream = co_stream_create("ostream", INT_TYPE(32), IMG_HEIGHT/2);   cpu_proc = co_process_create("cpu_proc",  (co_function)call_fpga,   3,                                 shrmem,   startsig, donesig);   reader = co_process_create("reader",    (co_function)to_stream,   3,                              startsig, shrmem,   istream);   prep_proc = co_process_create("prep_proc", (co_function)prep_run,    4,                                 istream,  row0,     row1,    row2);   filter_proc = co_process_create("filter",    (co_function)filter_run,  4,                                   row0,     row1,     row2,    ostream);   writer = co_process_create("writer",    (co_function)from_stream, 3,                              ostream,  shrmem,   donesig);   co_process_config(reader, co_loc, "PE0");   co_process_config(prep_proc, co_loc, "PE0");   co_process_config(filter_proc, co_loc, "PE0");   co_process_config(writer, co_loc, "PE0");   IF_SIM(error = cosim_logwindow_init();) }  co_architecture co_initialize() {   return(co_architecture_create("img_arch", "altera_nios2", config_img, NULL)); } 



    Practical FPGA Programming in C
    Practical FPGA Programming in C
    ISBN: 0131543180
    EAN: 2147483647
    Year: 2005
    Pages: 208

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net