Last active
December 29, 2018 12:11
-
-
Save LarsWerkman/66e65060e44f857ddcabd32aad67abab to your computer and use it in GitHub Desktop.
RGB pixels to FIFO
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 is a 2 clock fifo used for transferring data between | |
* clock domains. | |
* | |
* I assume here that the output (read) clock is >5X slower than the | |
* input (write) clock. | |
* | |
* Also, the fifo is just 1 word deep. | |
* | |
* Changes | |
* - 2015-07-03 issue when writing from low speed clock, empty_n goes | |
* high and stays high. The reader side will see and read, but | |
* after complete empty_n is still high. It will continue | |
* to read until empty_n is lowered based on the write side | |
* clock. | |
* The empty_n should go low once the reader reads. | |
* | |
*/ | |
module fifo ( | |
// Write side | |
wr_clk, | |
wr_data, | |
wr, | |
full, // means don't write any more | |
// Read side | |
rd_data, | |
rd_clk, | |
rd, | |
empty_n, // also means we can read | |
rst_n | |
); | |
parameter BUS_WIDTH = 32; | |
input [BUS_WIDTH-1:0] wr_data; | |
input wr_clk; | |
input wr; | |
output full; // Low-Means in side can write | |
output [BUS_WIDTH-1:0] rd_data; | |
input rd_clk; | |
input rd; | |
output empty_n; // High-Means out side can read | |
input rst_n; | |
reg [BUS_WIDTH-1:0] wr_data_r; | |
reg [BUS_WIDTH-1:0] rd_data; | |
/* | |
* these reg sets span accross 2 clock domtains | |
* CLK WR | CLK RD | |
* [wr_r] ------------------> | -> [wr_syn1] -> [wr_syn2] -\ | |
* <- [wr_ack2] <- [wr_ack1] | ---------------------------/ | |
* ^^^^^^^^^^ | | |
* Set wr_r when we get a wr | increment counter when we get | |
* Clr wr when we get wr_ack2 | wr_syn2, and syncronize data | |
* | |
*/ | |
reg wr_r, wr_syn1, wr_syn2, wr_ack1, wr_ack2; | |
reg rd_r, rd_syn1, rd_syn2, rd_ack1, rd_ack2; | |
reg wr_fifo_cnt; | |
reg rd_fifo_cnt; | |
assign full = wr_fifo_cnt == 1'b1; | |
assign empty_n = rd_fifo_cnt == 1'b1; | |
always @ (posedge rd_clk) | |
if (~rst_n) | |
begin | |
rd_fifo_cnt <= 1'b0; | |
{rd_ack2, rd_ack1} <= 2'b00; | |
{wr_syn2, wr_syn1} <= 2'b00; | |
end | |
else | |
begin | |
{rd_ack2, rd_ack1} <= {rd_ack1, rd_syn2}; | |
{wr_syn2, wr_syn1} <= {wr_syn1, wr_r}; | |
if (rd) | |
rd_r <= 1'b1; | |
else if (rd_ack2) | |
rd_r <= 1'b0; | |
if (rd) | |
rd_fifo_cnt <= 1'b0; | |
if ({wr_syn2, wr_syn1} == 2'b01) // if we want to just do increment 1 time, we can check posedge | |
rd_fifo_cnt <= 1'b1; | |
if (wr_syn2) | |
rd_data <= wr_data_r; | |
end | |
always @ (posedge wr_clk) | |
if (~rst_n) | |
begin | |
wr_fifo_cnt <= 1'b0; | |
{rd_syn2, rd_syn1} <= 2'b00; | |
{wr_ack2, wr_ack1} <= 2'b00; | |
end | |
else | |
begin | |
{wr_ack2, wr_ack1} <= {wr_ack1, wr_syn2}; | |
{rd_syn2, rd_syn1} <= {rd_syn1, rd_r}; | |
if (wr) | |
wr_r <= 1'b1; | |
if (wr_ack2) | |
wr_r <= 1'b0; | |
if (wr) | |
wr_fifo_cnt <= 1'b1; | |
if ({rd_syn2, rd_syn1} == 2'b01) | |
wr_fifo_cnt <= 1'b0; | |
// register write data on write | |
if (wr) | |
wr_data_r <= wr_data; | |
end | |
endmodule |
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
module rgb_to_fifo( | |
input clk, | |
input rst, | |
input [4:0] input_r, | |
input [4:0] input_g, | |
input [4:0] input_b, | |
input pixel_dclk, | |
input input_vsync | |
); | |
wire clock_100mhz; | |
wire clock_75mhz; | |
clock_pll clock_plls( | |
.CLK_IN1(clk), | |
.CLK_OUT1(clock_100mhz), | |
.CLK_OUT2(clock_75mhz) | |
); | |
localparam MAX_INPUT_PIXEL = 5'b11111; | |
localparam MAX_OUT_PIXEL = 8'b11111111; | |
localparam X_RES = 240; | |
localparam Y_RES = 160; | |
wire [7:0] red = map(input_r, MAX_INPUT_PIXEL, MAX_OUT_PIXEL); | |
wire [7:0] green = map(input_g, MAX_INPUT_PIXEL, MAX_OUT_PIXEL); | |
wire [7:0] blue = map(input_b, MAX_INPUT_PIXEL, MAX_OUT_PIXEL); | |
wire[54:0] write_fifo_data; | |
assign write_fifo_data[0:31] = {8'hFF, red, green, blue}; | |
wire [0:22] sdram_address = 0; | |
assign write_fifo_data[32:54] = sdram_address; | |
wire rst_n = ~rst; | |
wire full; | |
wire empty; | |
wire write_enable; | |
wire read_enable; | |
fifo #(.BUS_WIDTH(55)) wr_fifo( | |
.rst_n(rst_n), | |
.wr_clk(pixel_dclk), | |
.rd_clk(clock_100mhz), | |
.wr_data(write_fifo_data), | |
.rd_data(read_fifo_data), | |
.wr(write_enable), | |
.rd(read_enable), | |
.full(write_enable), | |
.rst_n(rst_n), | |
.empty(empty) | |
); | |
always@(posedge pixel_dclk) begin | |
write_enable = 1; | |
sdram_address <= sdram_address + 1; | |
end | |
function map; | |
input x, in_max, out_max; | |
begin | |
map = x * out_max / in_max; | |
end | |
endfunction | |
endmodule |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment