forked from maltanar/fpga-tidbits
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
203 additions
and
0 deletions.
There are no files selected for viewing
87 changes: 87 additions & 0 deletions
87
src/main/resources/cpp/platform-wrapper-tests/GrayScaleFilter.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
#include <iostream> | ||
#include <opencv2/opencv.hpp> | ||
using namespace std; | ||
|
||
#include "ExampleGrayScale.hpp" | ||
#include "platform.h" | ||
|
||
bool Run_ExampleGrayScale(WrapperRegDriver * platform, unsigned char *rgb_image, int rgb_size, unsigned char *grayscale_image) { | ||
ExampleGrayScale t(platform); | ||
int rgb_size_aligned = (rgb_size >> 3) << 3; | ||
int grayscale_size = rgb_size/3; | ||
int grayscale_size_aligned = (grayscale_size >> 3) << 3; | ||
cout << "Signature: " << hex << t.get_signature() << dec << endl; | ||
cout << "Running Grayscale accelerator on image of size " <<rgb_size_aligned <<" Bytes" <<endl; | ||
|
||
void * accelBuf = platform->allocAccelBuffer(rgb_size_aligned); | ||
void * accelBufRes = platform->allocAccelBuffer(grayscale_size_aligned); | ||
platform->copyBufferHostToAccel(rgb_image, accelBuf, rgb_size_aligned); | ||
|
||
t.set_baseAddr((AccelDblReg) accelBuf); | ||
t.set_resBaseAddr((AccelDblReg) accelBufRes); | ||
t.set_byteCount(rgb_size_aligned); | ||
t.set_resByteCount(grayscale_size_aligned); | ||
|
||
t.set_start(1); | ||
|
||
cout << "Waiting for Accel" <<endl; | ||
while(t.get_finished() != 1); | ||
cout << "Accel done" <<endl; | ||
unsigned int cc = t.get_cycleCount(); | ||
cout << "#cycles = " << cc << " cycles per word = " << endl; | ||
platform->copyBufferAccelToHost(accelBufRes, grayscale_image, grayscale_size_aligned); | ||
t.set_start(0); | ||
return true; | ||
} | ||
|
||
int main(int argc, char **argv) | ||
{ | ||
if(argc != 2) { | ||
std::cout << "Usage: ./program_name image_path" << std::endl; | ||
return -1; | ||
} | ||
|
||
cv::Mat image = cv::imread(argv[1], cv::IMREAD_COLOR); | ||
|
||
if(!image.data) { | ||
std::cout << "Error loading the image" << std::endl; | ||
return -1; | ||
} | ||
|
||
int width = image.cols; | ||
int height = image.rows; | ||
int rgb_size = height*width*3; | ||
|
||
// Create C-style arrays for the image and grayscale data | ||
unsigned char* rgb_data = new unsigned char[rgb_size]; | ||
unsigned char* grayscale_data = new unsigned char[height * width]; | ||
|
||
int idx_rgb = 0; | ||
int idx_gray = 0; | ||
|
||
for(int i = 0; i < height; i++) { | ||
for(int j = 0; j < width; j++) { | ||
unsigned char b = image.at<cv::Vec3b>(i, j)[0]; | ||
unsigned char g = image.at<cv::Vec3b>(i, j)[1]; | ||
unsigned char r = image.at<cv::Vec3b>(i, j)[2]; | ||
rgb_data[idx_rgb++] = r; | ||
rgb_data[idx_rgb++] = g; | ||
rgb_data[idx_rgb++] = b; | ||
} | ||
} | ||
|
||
WrapperRegDriver * platform = initPlatform(); | ||
|
||
Run_ExampleGrayScale(platform, rgb_data, rgb_size, grayscale_data); | ||
|
||
deinitPlatform(platform); | ||
|
||
// Convert the grayscale_data back to a cv::Mat for saving | ||
cv::Mat grayscale_image(height, width, CV_8U, grayscale_data); | ||
cv::imwrite("grayscale_output.jpg", grayscale_image); | ||
|
||
delete[] rgb_data; | ||
delete[] grayscale_data; | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
107 changes: 107 additions & 0 deletions
107
src/main/scala/fpgatidbits/examples/ExampleGrayScale.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
package fpgatidbits.examples | ||
|
||
import chisel3._ | ||
import chisel3.util.{Decoupled, DecoupledIO} | ||
import fpgatidbits.PlatformWrapper._ | ||
import fpgatidbits.dma._ | ||
|
||
class ExampleGrayScaleIO(p: PlatformWrapperParams) extends GenericAcceleratorIF(1, p) { | ||
val start = Input(Bool()) | ||
val finished = Output(Bool()) | ||
val baseAddr = Input(UInt(64.W)) | ||
val byteCount = Input(UInt(32.W)) | ||
val resBaseAddr = Input(UInt(64.W)) | ||
val resByteCount = Input(UInt(32.W)) | ||
val cycleCount = Output(UInt(32.W)) | ||
} | ||
// read and sum a contiguous stream of 32-bit uints from main memory | ||
class ExampleGrayScale(p: PlatformWrapperParams) extends GenericAccelerator(p) { | ||
val numMemPorts = 1 | ||
val io = IO(new ExampleGrayScaleIO(p)) | ||
io.signature := makeDefaultSignature() | ||
|
||
val rdP = new StreamReaderParams( | ||
streamWidth = 24, fifoElems = 8, mem = p.toMemReqParams(), | ||
maxBeats = 1, chanID = 0, disableThrottle = true | ||
) | ||
|
||
val wrP = new StreamWriterParams( | ||
streamWidth = 8, mem=p.toMemReqParams(), chanID = 0, maxBeats = 1 | ||
) | ||
|
||
val reader = Module(new StreamReader(rdP)).io | ||
val writer = Module(new StreamWriter(wrP)).io | ||
|
||
reader.start := io.start | ||
reader.baseAddr := io.baseAddr | ||
reader.byteCount := io.byteCount | ||
reader.doInit := false.B | ||
reader.initCount := 8.U | ||
|
||
writer.start := io.start | ||
writer.baseAddr := io.resBaseAddr | ||
writer.byteCount := io.resByteCount | ||
|
||
io.finished := writer.finished | ||
|
||
reader.req <> io.memPort(0).memRdReq | ||
io.memPort(0).memRdRsp <> reader.rsp | ||
writer.req <> io.memPort(0).memWrReq | ||
writer.wdat <> io.memPort(0).memWrDat | ||
writer.rsp <> io.memPort(0).memWrRsp | ||
|
||
val grayFilter = Module(new GrayScaleFilter) | ||
grayFilter.rgbIn.valid := reader.out.valid | ||
grayFilter.rgbIn.bits := reader.out.bits.asTypeOf(new Colour) | ||
reader.out.ready := grayFilter.rgbIn.ready | ||
|
||
grayFilter.grayOut <> writer.in | ||
|
||
val regCycleCount = RegInit(0.U(32.W)) | ||
io.cycleCount := regCycleCount | ||
when(!io.start) {regCycleCount := 0.U} | ||
.elsewhen(io.start & !io.finished) {regCycleCount := regCycleCount + 1.U} | ||
} | ||
|
||
class Colour extends Bundle { | ||
val r = UInt(8.W) | ||
val g = UInt(8.W) | ||
val b = UInt(8.W) | ||
} | ||
|
||
class GrayScaleFilter extends Module { | ||
val rgbIn = IO(Flipped(Decoupled(new Colour))) | ||
val grayOut = IO(Decoupled(UInt(8.W))) | ||
|
||
val s1_valid = RegInit(false.B) | ||
val s1_r1Shifted = RegInit(0.U(8.W)) | ||
val s1_r2Shifted = RegInit(0.U(8.W)) | ||
val s1_g1Shifted = RegInit(0.U(8.W)) | ||
val s1_g2Shifted = RegInit(0.U(8.W)) | ||
val s1_b1Shifted = RegInit(0.U(8.W)) | ||
val s1_b2Shifted = RegInit(0.U(8.W)) | ||
|
||
val s2_valid = RegInit(false.B) | ||
val s2_gray = RegInit(0.U(8.W)) | ||
|
||
rgbIn.ready := !s2_valid || grayOut.fire | ||
grayOut.valid := s2_valid | ||
grayOut.bits := s2_gray | ||
|
||
when(rgbIn.fire) { | ||
// Stage 1 | ||
s1_valid := true.B | ||
val rgb = rgbIn.bits | ||
val (r,g,b) = (rgb.r, rgb.g, rgb.b) | ||
s1_r1Shifted := (r >> 2).asUInt | ||
s1_r2Shifted := (r >> 5).asUInt | ||
s1_g1Shifted := (g >> 1).asUInt | ||
s1_g2Shifted := (g >> 4).asUInt | ||
s1_b1Shifted := (b >> 4).asUInt | ||
s1_b2Shifted := (b >> 5).asUInt | ||
|
||
// Stage 2 | ||
s2_valid := s1_valid | ||
s2_gray := s1_r1Shifted + s1_r2Shifted + s1_g1Shifted + s1_g2Shifted + s1_b1Shifted + s1_b2Shifted | ||
} | ||
} |