URL
https://opencores.org/ocsvn/fpga-median/fpga-median/trunk
Subversion Repositories fpga-median
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/fpga-median/trunk/rtl/median.v
0,0 → 1,307
// +---------------------------------------------------------------------------- |
// Universidade Federal da Bahia |
//------------------------------------------------------------------------------ |
// PROJECT: FPGA Median Filter |
//------------------------------------------------------------------------------ |
// FILE NAME : median.v |
// AUTHOR : João Carlos Bittencourt |
// AUTHOR'S E-MAIL : joaocarlos@ieee.org |
// ----------------------------------------------------------------------------- |
// RELEASE HISTORY |
// VERSION DATE AUTHOR DESCRIPTION |
// 1.0 2013-08-13 joao.nunes initial version |
// ----------------------------------------------------------------------------- |
// KEYWORDS: median, filter, image processing |
// ----------------------------------------------------------------------------- |
// PURPOSE: Top level entity of the Median Filter algorithm datapath. |
// ----------------------------------------------------------------------------- |
`define DEBUG |
|
module median |
#( |
parameter MEM_DATA_WIDTH = 32, |
parameter LUT_ADDR_WIDTH = 10, // Input LUTs |
parameter MEM_ADDR_WIDTH = 10, // Output Memory |
parameter PIXEL_DATA_WIDTH = 8, |
parameter IMG_WIDTH = 320, |
parameter IMG_HEIGHT = 320 |
)( |
input clk, // Clock |
input rst_n, // Asynchronous reset active low |
input [31:0] word0, |
input [31:0] word1, |
input [31:0] word2, |
|
// Test signals |
`ifdef DEBUG |
output [PIXEL_DATA_WIDTH-1:0] pixel1, |
output [PIXEL_DATA_WIDTH-1:0] pixel2, |
output [PIXEL_DATA_WIDTH-1:0] pixel3, |
output [PIXEL_DATA_WIDTH-1:0] pixel4, |
`else |
output [MEM_DATA_WIDTH-1:0] median_word, |
`endif |
output [LUT_ADDR_WIDTH-1:0] raddr_a, |
output [LUT_ADDR_WIDTH-1:0] raddr_b, |
output [LUT_ADDR_WIDTH-1:0] raddr_c, |
|
output [MEM_ADDR_WIDTH-1:0] waddr |
); |
|
wire [PIXEL_DATA_WIDTH-1:0] x2_y1; |
wire [PIXEL_DATA_WIDTH-1:0] x2_y0; |
wire [PIXEL_DATA_WIDTH-1:0] x2_ym1; |
wire [PIXEL_DATA_WIDTH-1:0] x1_y1; |
wire [PIXEL_DATA_WIDTH-1:0] x1_y0; |
wire [PIXEL_DATA_WIDTH-1:0] x1_ym1; |
wire [PIXEL_DATA_WIDTH-1:0] x0_y1; |
wire [PIXEL_DATA_WIDTH-1:0] x0_y0; |
wire [PIXEL_DATA_WIDTH-1:0] x0_ym1; |
wire [PIXEL_DATA_WIDTH-1:0] xm1_y1; |
wire [PIXEL_DATA_WIDTH-1:0] xm1_y0; |
wire [PIXEL_DATA_WIDTH-1:0] xm1_ym1; |
|
assign x2_y1 = word0[PIXEL_DATA_WIDTH-1:0]; |
assign x2_y0 = word1[PIXEL_DATA_WIDTH-1:0]; |
assign x2_ym1 = word2[PIXEL_DATA_WIDTH-1:0]; |
|
assign x1_y1 = word0[(PIXEL_DATA_WIDTH*2)-1:PIXEL_DATA_WIDTH]; |
assign x1_y0 = word1[(PIXEL_DATA_WIDTH*2)-1:PIXEL_DATA_WIDTH]; |
assign x1_ym1 = word2[(PIXEL_DATA_WIDTH*2)-1:PIXEL_DATA_WIDTH]; |
|
assign x0_y1 = word0[(PIXEL_DATA_WIDTH*3)-1:(PIXEL_DATA_WIDTH*2)]; |
assign x0_y0 = word1[(PIXEL_DATA_WIDTH*3)-1:(PIXEL_DATA_WIDTH*2)]; |
assign x0_ym1 = word2[(PIXEL_DATA_WIDTH*3)-1:(PIXEL_DATA_WIDTH*2)]; |
|
assign xm1_y1 = word0[(PIXEL_DATA_WIDTH*4)-1:(PIXEL_DATA_WIDTH*3)]; |
assign xm1_y0 = word1[(PIXEL_DATA_WIDTH*4)-1:(PIXEL_DATA_WIDTH*3)]; |
assign xm1_ym1 = word2[(PIXEL_DATA_WIDTH*4)-1:(PIXEL_DATA_WIDTH*3)]; |
|
// wire [PIXEL_DATA_WIDTH-1:0] pixel1_sig; |
// wire [PIXEL_DATA_WIDTH-1:0] pixel2_sig; |
// wire [PIXEL_DATA_WIDTH-1:0] pixel3_sig; |
// wire [PIXEL_DATA_WIDTH-1:0] pixel4_sig; |
|
`ifndef DEBUG |
assign median_word = {pixel1,pixel2,pixel3,pixel4}; |
`endif |
|
// Common network output signals |
wire [PIXEL_DATA_WIDTH-1:0] c3l; |
wire [PIXEL_DATA_WIDTH-1:0] c3h; |
wire [PIXEL_DATA_WIDTH-1:0] c3m; |
wire [PIXEL_DATA_WIDTH-1:0] c3l_reg; |
wire [PIXEL_DATA_WIDTH-1:0] c3h_reg; |
wire [PIXEL_DATA_WIDTH-1:0] c3m_reg; |
wire [PIXEL_DATA_WIDTH-1:0] c2l; |
wire [PIXEL_DATA_WIDTH-1:0] c2h; |
wire [PIXEL_DATA_WIDTH-1:0] c2m; |
wire [PIXEL_DATA_WIDTH-1:0] c2l_reg; |
wire [PIXEL_DATA_WIDTH-1:0] c2h_reg; |
wire [PIXEL_DATA_WIDTH-1:0] c2m_reg; |
wire [PIXEL_DATA_WIDTH-1:0] c1l; |
wire [PIXEL_DATA_WIDTH-1:0] c1h; |
wire [PIXEL_DATA_WIDTH-1:0] c1m; |
wire [PIXEL_DATA_WIDTH-1:0] c0h; |
wire [PIXEL_DATA_WIDTH-1:0] c0m; |
wire [PIXEL_DATA_WIDTH-1:0] c0l; |
|
// Delay signals to be placed over the output registers |
wire [PIXEL_DATA_WIDTH-1:0] p1_sig; |
wire [PIXEL_DATA_WIDTH-1:0] p2_sig; |
wire [PIXEL_DATA_WIDTH-1:0] p3_sig; |
|
//------------------------------------------------------------ |
// Windowing Memory Address Controller |
//------------------------------------------------------------ |
state_machine |
#( |
.LUT_ADDR_WIDTH(LUT_ADDR_WIDTH), |
.IMG_WIDTH(IMG_WIDTH), |
.IMG_HEIGHT(IMG_HEIGHT) |
) window_contol ( |
.clk(clk), // Clock |
.rst_n(rst_n), // Asynchronous reset active low |
|
.raddr_a(raddr_a), |
.raddr_b(raddr_b), |
.raddr_c(raddr_c), |
|
.waddr(waddr) |
); |
|
//------------------------------------------------------------ |
// Pixel registers |
//------------------------------------------------------------ |
// always @(posedge clk or negedge rst_n) |
// begin : pixel_reg |
// if(~rst_n) begin |
// pixel1 <= {PIXEL_DATA_WIDTH{1'b0}}; |
// pixel2 <= {PIXEL_DATA_WIDTH{1'b0}}; |
// pixel3 <= {PIXEL_DATA_WIDTH{1'b0}}; |
// pixel4 <= {PIXEL_DATA_WIDTH{1'b0}}; |
// end else begin |
// pixel1 <= pixel1_sig; |
// pixel2 <= pixel2_sig; |
// pixel3 <= pixel3_sig; |
// //pixel4 <= pixel4_sig; |
// end |
// end |
|
//------------------------------------------------------------ |
// Input datapath common network |
//------------------------------------------------------------ |
common_network |
#( |
.DATA_WIDTH(PIXEL_DATA_WIDTH) |
) common_network_u0 ( |
.x2_y1(x2_y1), |
.x2_y0(x2_y0), |
.x2_ym1(x2_ym1), |
.x1_y1(x1_y1), |
.x1_y0(x1_y0), |
.x1_ym1(x1_ym1), |
.x0_y1(x0_y1), |
.x0_y0(x0_y0), |
.x0_ym1(x0_ym1), |
.xm1_y1(xm1_y1), |
.xm1_y0(xm1_y0), |
.xm1_ym1(xm1_ym1), |
|
.c3l(c3l), |
.c3h(c3h), |
.c3m(c3m), |
.c2l(c2l), |
.c2h(c2h), |
.c2m(c2m), |
.c1l(c1l), |
.c1h(c1h), |
.c1m(c1m), |
.c0h(c0h), |
.c0m(c0m), |
.c0l(c0l) |
); |
|
//------------------------------------------------------------ |
// Pipeline Registers |
//------------------------------------------------------------ |
dff_3_pipe |
#( |
.DATA_WIDTH(PIXEL_DATA_WIDTH) |
) dff_c3_pipe ( |
.clk(clk), |
.rst_n(rst_n), |
.d0(c3h), |
.d1(c3m), |
.d2(c3l), |
|
.q0(c3h_reg), |
.q1(c3m_reg), |
.q2(c3l_reg) |
); |
|
dff_3_pipe |
#( |
.DATA_WIDTH(PIXEL_DATA_WIDTH) |
) dff_c2_pipe ( |
.clk(clk), |
.rst_n(rst_n), |
.d0(c2h), |
.d1(c2m), |
.d2(c2l), |
|
.q0(c2h_reg), |
.q1(c2m_reg), |
.q2(c2l_reg) |
); |
|
// Output pieline registers (P1, P2, P3) |
dff_3_pipe |
#( |
.DATA_WIDTH(PIXEL_DATA_WIDTH) |
) dff_out_pipe ( |
.clk(clk), |
.rst_n(rst_n), |
.d0(p1_sig), |
.d1(p2_sig), |
.d2(p3_sig), |
|
.q0(pixel1), |
.q1(pixel2), |
.q2(pixel3) |
); |
|
//------------------------------------------------------------ |
// Median Filter Pixel Network |
//------------------------------------------------------------ |
|
// Pixel 1 |
pixel_network |
#( |
.DATA_WIDTH(PIXEL_DATA_WIDTH) |
) pixel_network_u0 ( |
.c3h(c1h), |
.c3m(c1m), |
.c3l(c1l), |
.c2h(c0h), |
.c2m(c0m), |
.c2l(c0l), |
.c1h(c3h_reg), |
.c1m(c3m_reg), |
.c1l(c3l_reg), |
|
.median(p1_sig) |
); |
|
pixel_network |
#( |
.DATA_WIDTH(PIXEL_DATA_WIDTH) |
) pixel_network_u1 ( |
.c3h(c2h), |
.c3m(c2m), |
.c3l(c2l), |
.c2h(c1h), |
.c2m(c1m), |
.c2l(c1l), |
.c1h(c0h), |
.c1m(c0m), |
.c1l(c0l), |
|
.median(p2_sig) |
); |
|
pixel_network |
#( |
.DATA_WIDTH(PIXEL_DATA_WIDTH) |
) pixel_network_u2 ( |
.c3h(c3h), |
.c3m(c3m), |
.c3l(c3l), |
.c2h(c2h), |
.c2m(c2m), |
.c2l(c2l), |
.c1h(c1h), |
.c1m(c1m), |
.c1l(c1l), |
|
.median(p3_sig) |
); |
|
pixel_network |
#( |
.DATA_WIDTH(PIXEL_DATA_WIDTH) |
) pixel_network_u3 ( |
.c3h(c0h), |
.c3m(c0m), |
.c3l(c0l), |
.c2h(c3h_reg), |
.c2m(c3m_reg), |
.c2l(c3l_reg), |
.c1h(c2h_reg), |
.c1m(c2m_reg), |
.c1l(c2l_reg), |
|
.median(pixel4) |
); |
|
endmodule |
/fpga-median/trunk/rtl/dff_3_pipe.v
0,0 → 1,46
// +---------------------------------------------------------------------------- |
// Universidade Federal da Bahia |
//------------------------------------------------------------------------------ |
// PROJECT: FPGA Median Filter |
//------------------------------------------------------------------------------ |
// FILE NAME : pixel_network.v |
// AUTHOR : João Carlos Bittencourt |
// AUTHOR'S E-MAIL : joaocarlos@ieee.org |
// ----------------------------------------------------------------------------- |
// RELEASE HISTORY |
// VERSION DATE AUTHOR DESCRIPTION |
// 1.0 2013-08-13 joao.nunes initial version |
// ----------------------------------------------------------------------------- |
// KEYWORDS: dff, flip-flop, register bank |
// ----------------------------------------------------------------------------- |
// PURPOSE: Group median pipeline registers. |
// ----------------------------------------------------------------------------- |
module dff_3_pipe |
#( |
parameter DATA_WIDTH = 8 |
)( |
input clk, |
input rst_n, |
input [DATA_WIDTH-1:0] d0, |
input [DATA_WIDTH-1:0] d1, |
input [DATA_WIDTH-1:0] d2, |
|
output reg [DATA_WIDTH-1:0] q0, |
output reg [DATA_WIDTH-1:0] q1, |
output reg [DATA_WIDTH-1:0] q2 |
); |
|
always @(posedge clk or negedge rst_n) |
begin : register_bank_3u |
if(~rst_n) begin |
q0 <= {DATA_WIDTH{1'b0}}; |
q1 <= {DATA_WIDTH{1'b0}}; |
q2 <= {DATA_WIDTH{1'b0}}; |
end else begin |
q0 <= d0; |
q1 <= d1; |
q2 <= d2; |
end |
end |
|
endmodule |
/fpga-median/trunk/rtl/common_network.v
0,0 → 1,251
// +---------------------------------------------------------------------------- |
// Universidade Federal da Bahia |
//------------------------------------------------------------------------------ |
// PROJECT: FPGA Median Filter |
//------------------------------------------------------------------------------ |
// FILE NAME : pixel_network.v |
// AUTHOR : João Carlos Bittencourt |
// AUTHOR'S E-MAIL : joaocarlos@ieee.org |
// ----------------------------------------------------------------------------- |
// RELEASE HISTORY |
// VERSION DATE AUTHOR DESCRIPTION |
// 1.0 2013-08-13 joao.nunes initial version |
// ----------------------------------------------------------------------------- |
// KEYWORDS: comparator, low, high, median |
// ----------------------------------------------------------------------------- |
// PURPOSE: Obtain the Median of a 3x3 mask. |
// ----------------------------------------------------------------------------- |
module common_network |
#( |
parameter DATA_WIDTH = 8 |
)( |
input [DATA_WIDTH-1:0] x2_y1, |
input [DATA_WIDTH-1:0] x2_y0, |
input [DATA_WIDTH-1:0] x2_ym1, |
input [DATA_WIDTH-1:0] x1_y1, |
input [DATA_WIDTH-1:0] x1_y0, |
input [DATA_WIDTH-1:0] x1_ym1, |
input [DATA_WIDTH-1:0] x0_y1, |
input [DATA_WIDTH-1:0] x0_y0, |
input [DATA_WIDTH-1:0] x0_ym1, |
input [DATA_WIDTH-1:0] xm1_y1, |
input [DATA_WIDTH-1:0] xm1_y0, |
input [DATA_WIDTH-1:0] xm1_ym1, |
|
output [DATA_WIDTH-1:0] c3l, |
output [DATA_WIDTH-1:0] c3h, |
output [DATA_WIDTH-1:0] c3m, |
output [DATA_WIDTH-1:0] c2l, |
output [DATA_WIDTH-1:0] c2h, |
output [DATA_WIDTH-1:0] c2m, |
output [DATA_WIDTH-1:0] c1l, |
output [DATA_WIDTH-1:0] c1h, |
output [DATA_WIDTH-1:0] c1m, |
output [DATA_WIDTH-1:0] c0h, |
output [DATA_WIDTH-1:0] c0m, |
output [DATA_WIDTH-1:0] c0l |
); |
|
// Connection signals |
wire [DATA_WIDTH-1:0] node_u0_hi; |
wire [DATA_WIDTH-1:0] node_u0_lo; |
wire [DATA_WIDTH-1:0] node_u1_hi; |
wire [DATA_WIDTH-1:0] node_u1_lo; |
wire [DATA_WIDTH-1:0] node_u2_hi; |
wire [DATA_WIDTH-1:0] node_u2_lo; |
wire [DATA_WIDTH-1:0] node_u3_hi; |
wire [DATA_WIDTH-1:0] node_u3_lo; |
wire [DATA_WIDTH-1:0] node_u4_hi; |
wire [DATA_WIDTH-1:0] node_u4_lo; |
wire [DATA_WIDTH-1:0] node_u5_hi; |
wire [DATA_WIDTH-1:0] node_u5_lo; |
wire [DATA_WIDTH-1:0] node_u6_hi; |
wire [DATA_WIDTH-1:0] node_u6_lo; |
wire [DATA_WIDTH-1:0] node_u7_hi; |
wire [DATA_WIDTH-1:0] node_u7_lo; |
wire [DATA_WIDTH-1:0] node_u8_hi; |
wire [DATA_WIDTH-1:0] node_u8_lo; |
wire [DATA_WIDTH-1:0] node_u9_hi; |
wire [DATA_WIDTH-1:0] node_u9_lo; |
wire [DATA_WIDTH-1:0] node_u10_hi; |
wire [DATA_WIDTH-1:0] node_u10_lo; |
wire [DATA_WIDTH-1:0] node_u11_hi; |
wire [DATA_WIDTH-1:0] node_u11_lo; |
wire [DATA_WIDTH-1:0] node_u12_hi; |
wire [DATA_WIDTH-1:0] node_u12_lo; |
|
// Output assignment |
assign c3l = node_u4_lo; |
assign c3h = node_u8_hi; |
assign c3m = node_u8_lo; |
assign c2l = node_u5_lo; |
assign c2h = node_u9_hi; |
assign c2m = node_u9_lo; |
assign c1l = node_u6_lo; |
assign c1h = node_u10_hi; |
assign c1m = node_u10_lo; |
assign c0h = node_u11_hi; |
assign c0m = node_u11_lo; |
assign c0l = node_u7_lo; |
|
// Column 3 |
node |
#( |
.DATA_WIDTH(DATA_WIDTH), |
.LOW_MUX(1), // enable low output |
.HI_MUX(1) // enable high output |
) node_u0 ( |
.data_a(x2_y1), |
.data_b(x2_y0), |
|
.data_hi(node_u0_hi), |
.data_lo(node_u0_lo) |
); |
|
node |
#( |
.DATA_WIDTH(DATA_WIDTH), |
.LOW_MUX(1), // enable low output |
.HI_MUX(1) // enable high output |
) node_u1 ( |
.data_a(x1_y1), |
.data_b(x1_y0), |
|
.data_hi(node_u1_hi), |
.data_lo(node_u1_lo) |
); |
|
node |
#( |
.DATA_WIDTH(DATA_WIDTH), |
.LOW_MUX(1), // enable low output |
.HI_MUX(1) // enable high output |
) node_u2 ( |
.data_a(x0_y1), |
.data_b(x0_y0), |
|
.data_hi(node_u2_hi), |
.data_lo(node_u2_lo) |
); |
|
// Column 2 |
node |
#( |
.DATA_WIDTH(DATA_WIDTH), |
.LOW_MUX(1), // enable low output |
.HI_MUX(1) // enable high output |
) node_u3 ( |
.data_a(xm1_y1), |
.data_b(xm1_y0), |
|
.data_hi(node_u3_hi), |
.data_lo(node_u3_lo) |
); |
|
node |
#( |
.DATA_WIDTH(DATA_WIDTH), |
.LOW_MUX(1), // enable low output |
.HI_MUX(1) // enable high output |
) node_u4 ( |
.data_a(node_u0_lo), |
.data_b(x2_ym1), |
|
.data_hi(node_u4_hi), |
.data_lo(node_u4_lo) |
); |
|
node |
#( |
.DATA_WIDTH(DATA_WIDTH), |
.LOW_MUX(1), // enable low output |
.HI_MUX(1) // enable high output |
) node_u5 ( |
.data_a(node_u1_lo), |
.data_b(x1_ym1), |
|
.data_hi(node_u5_hi), |
.data_lo(node_u5_lo) |
); |
|
// Column 1 |
node |
#( |
.DATA_WIDTH(DATA_WIDTH), |
.LOW_MUX(1), // enable low output |
.HI_MUX(1) // enable high output |
) node_u6 ( |
.data_a(node_u2_lo), |
.data_b(x0_ym1), |
|
.data_hi(node_u6_hi), |
.data_lo(node_u6_lo) |
); |
|
node |
#( |
.DATA_WIDTH(DATA_WIDTH), |
.LOW_MUX(1), // enable low output |
.HI_MUX(1) // enable high output |
) node_u7 ( |
.data_a(node_u3_lo), |
.data_b(xm1_ym1), |
|
.data_hi(node_u7_hi), |
.data_lo(node_u7_lo) |
); |
|
node |
#( |
.DATA_WIDTH(DATA_WIDTH), |
.LOW_MUX(1), // enable low output |
.HI_MUX(1) // enable high output |
) node_u8 ( |
.data_a(node_u0_hi), |
.data_b(node_u4_hi), |
|
.data_hi(node_u8_hi), |
.data_lo(node_u8_lo) |
); |
|
// Column 0 |
node |
#( |
.DATA_WIDTH(DATA_WIDTH), |
.LOW_MUX(1), // enable low output |
.HI_MUX(1) // enable high output |
) node_u9 ( |
.data_a(node_u1_hi), |
.data_b(node_u5_hi), |
|
.data_hi(node_u9_hi), |
.data_lo(node_u9_lo) |
); |
|
node |
#( |
.DATA_WIDTH(DATA_WIDTH), |
.LOW_MUX(1), // enable low output |
.HI_MUX(1) // enable high output |
) node_u10 ( |
.data_a(node_u2_hi), |
.data_b(node_u6_hi), |
|
.data_hi(node_u10_hi), |
.data_lo(node_u10_lo) |
); |
|
node |
#( |
.DATA_WIDTH(DATA_WIDTH), |
.LOW_MUX(1), // enable low output |
.HI_MUX(1) // enable high output |
) node_u11 ( |
.data_a(node_u3_hi), |
.data_b(node_u7_hi), |
|
.data_hi(node_u11_hi), |
.data_lo(node_u11_lo) |
); |
|
endmodule |
/fpga-median/trunk/rtl/state_machine.v
0,0 → 1,98
// +---------------------------------------------------------------------------- |
// Universidade Federal da Bahia |
//------------------------------------------------------------------------------ |
// PROJECT: FPGA Median Filter |
//------------------------------------------------------------------------------ |
// FILE NAME : median.v |
// AUTHOR : Joo Carlos Bittencourt |
// AUTHOR'S E-MAIL : joaocarlos@ieee.org |
// ----------------------------------------------------------------------------- |
// RELEASE HISTORY |
// VERSION DATE AUTHOR DESCRIPTION |
// 1.0 2013-08-13 joao.nunes initial version |
// 2.0 2013-09-06 laur.rami fix minnor issues on memory address |
// ----------------------------------------------------------------------------- |
// KEYWORDS: median, filter, image processing, state machine |
// ----------------------------------------------------------------------------- |
// PURPOSE: Windowing Memory Address Controller. |
// ----------------------------------------------------------------------------- |
module state_machine |
#( |
parameter LUT_ADDR_WIDTH = 10, |
parameter IMG_WIDTH = 234, |
parameter IMG_HEIGHT = 234 |
)( |
input clk, // Clock |
input rst_n, // Asynchronous reset active low |
|
output reg [LUT_ADDR_WIDTH-1:0] raddr_a, |
output reg [LUT_ADDR_WIDTH-1:0] raddr_b, |
output reg [LUT_ADDR_WIDTH-1:0] raddr_c, |
output reg [LUT_ADDR_WIDTH-1:0] waddr, |
output reg [1:0] window_line_counter, |
output reg [9:0] window_column_counter, |
output reg [9:0] memory_shift |
); |
|
reg valid; |
|
always @(posedge clk or negedge rst_n) |
begin : out_memory_counter |
if(~rst_n) begin |
waddr <= {LUT_ADDR_WIDTH{1'b0}}; |
end else if(valid) begin |
waddr <= waddr + 1'b1; |
end |
end |
|
always @(posedge clk or negedge rst_n) |
begin : addr_counter |
if(~rst_n) begin |
window_column_counter <= 10'd0; |
window_line_counter <= 2'b00; |
raddr_a <= {LUT_ADDR_WIDTH{1'b0}}; |
raddr_b <= {LUT_ADDR_WIDTH{1'b0}}; |
raddr_c <= {LUT_ADDR_WIDTH{1'b0}}; |
end else begin |
if(window_column_counter != ((IMG_WIDTH/4)-1)) begin |
window_column_counter <= window_column_counter + 1'b1; |
valid <= 1'b1; |
raddr_a <= raddr_a + 1'b1; |
raddr_b <= raddr_b + 1'b1; |
raddr_c <= raddr_c + 1'b1; |
end else begin |
window_column_counter <= 10'd0; |
case (window_line_counter) |
2'b00 : |
begin |
raddr_a <= raddr_a + 1'b1; |
raddr_b <= raddr_b - window_column_counter; |
raddr_c <= raddr_c - window_column_counter; |
window_line_counter = window_line_counter + 1'b1; |
end |
2'b01 : |
begin |
raddr_b <= raddr_b + 1'b1; |
raddr_a <= raddr_a - window_column_counter; |
raddr_c <= raddr_c - window_column_counter; |
window_line_counter = window_line_counter + 1'b1; |
end |
2'b10 : |
begin |
raddr_b <= raddr_b - window_column_counter; |
raddr_a <= raddr_a - window_column_counter; |
raddr_c <= raddr_c + 1'b1; |
window_line_counter = 2'b00; |
end |
default : |
begin |
raddr_a <= {LUT_ADDR_WIDTH{1'b0}}; |
raddr_b <= {LUT_ADDR_WIDTH{1'b0}}; |
raddr_c <= {LUT_ADDR_WIDTH{1'b0}}; |
end |
endcase |
end |
end |
end |
|
endmodule |
/fpga-median/trunk/rtl/node.v
0,0 → 1,69
// +---------------------------------------------------------------------------- |
// Universidade Federal da Bahia |
//------------------------------------------------------------------------------ |
// PROJECT: FPGA Median Filter |
//------------------------------------------------------------------------------ |
// FILE NAME : node.v |
// AUTHOR : João Carlos Bittencourt |
// AUTHOR'S E-MAIL : joaocarlos@ieee.org |
// ----------------------------------------------------------------------------- |
// RELEASE HISTORY |
// VERSION DATE AUTHOR DESCRIPTION |
// 1.0 2013-08-13 joao.nunes initial version |
// ----------------------------------------------------------------------------- |
// KEYWORDS: comparator, low, hight, median |
// ----------------------------------------------------------------------------- |
// PURPOSE: Compare two input values and return the low and high values. |
// ----------------------------------------------------------------------------- |
module node |
#( |
parameter DATA_WIDTH = 8, |
parameter LOW_MUX = 1, // disable low output |
parameter HI_MUX = 1 // disable hight output |
)( |
input [DATA_WIDTH-1:0] data_a, |
input [DATA_WIDTH-1:0] data_b, |
|
output reg [DATA_WIDTH-1:0] data_hi, |
output reg [DATA_WIDTH-1:0] data_lo |
); |
|
|
reg sel0; |
|
always @(*) |
begin : comparator |
if(data_a < data_b) begin |
sel0 = 1'b0; // data_a : lo / data_b : hi |
end else begin |
sel0 = 1'b1; // data_b : lo / data_a : hi |
end |
end |
|
|
always @(*) |
begin : mux_lo_hi |
case (sel0) |
1'b0 : |
begin |
if(LOW_MUX == 1) |
data_lo = data_a; |
if(HI_MUX == 1) |
data_hi = data_b; |
end |
1'b1 : |
begin |
if(LOW_MUX == 1) |
data_lo = data_b; |
if(HI_MUX == 1) |
data_hi = data_a; |
end |
default : |
begin |
data_lo = {DATA_WIDTH{1'b0}}; |
data_hi = {DATA_WIDTH{1'b0}}; |
end |
endcase |
end |
|
endmodule |
/fpga-median/trunk/rtl/dual_port_ram.v
0,0 → 1,41
//*******************************************************************// |
//-------------------------------------------------------------------// |
// File name : dual_port_ram.v |
// File contents : Parameterized memory for syncronous fifo |
// |
// Design Engineer : Igor Dantas |
// Last Changed : 10/27/2008 09:00 |
//-------------------------------------------------------------------// |
//*******************************************************************// |
|
`timescale 1ns/10ps |
|
module dual_port_ram |
#( |
parameter MEMFILE = "", |
parameter DATA_WIDTH = 'd32, |
parameter ADDR_WIDTH = 14 |
) |
( |
input clk, |
input r_ena, |
input w_ena, |
input [DATA_WIDTH-1:0] w_data, |
input [ADDR_WIDTH-1:0] w_addr, |
input [ADDR_WIDTH-1:0] r_addr, |
output reg [DATA_WIDTH-1:0] r_data |
); |
|
//The Register memory |
reg [DATA_WIDTH-1:0] mem[0:2**ADDR_WIDTH-1]; |
// synchronous read and write when enabled |
always @ (posedge clk) begin |
if (w_ena) mem[w_addr] <= w_data; |
if (r_ena) r_data <= mem[r_addr]; |
end |
|
initial $readmemh(MEMFILE, mem); |
|
|
endmodule |
|
fpga-median/trunk/rtl/dual_port_ram.v
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: fpga-median/trunk/rtl/pixel_network.v
===================================================================
--- fpga-median/trunk/rtl/pixel_network.v (nonexistent)
+++ fpga-median/trunk/rtl/pixel_network.v (revision 2)
@@ -0,0 +1,175 @@
+// +----------------------------------------------------------------------------
+// Universidade Federal da Bahia
+//------------------------------------------------------------------------------
+// PROJECT: FPGA Median Filter
+//------------------------------------------------------------------------------
+// FILE NAME : pixel_network.v
+// AUTHOR : João Carlos Bittencourt
+// AUTHOR'S E-MAIL : joaocarlos@ieee.org
+// -----------------------------------------------------------------------------
+// RELEASE HISTORY
+// VERSION DATE AUTHOR DESCRIPTION
+// 1.0 2013-08-13 joao.nunes initial version
+// -----------------------------------------------------------------------------
+// KEYWORDS: comparator, low, hight, median
+// -----------------------------------------------------------------------------
+// PURPOSE: Obtain the Median of a 3x3 mask.
+// -----------------------------------------------------------------------------
+module pixel_network
+#(
+ parameter DATA_WIDTH = 8
+)(
+ input [DATA_WIDTH-1:0] c3h,
+ input [DATA_WIDTH-1:0] c3m,
+ input [DATA_WIDTH-1:0] c3l,
+ input [DATA_WIDTH-1:0] c2h,
+ input [DATA_WIDTH-1:0] c2m,
+ input [DATA_WIDTH-1:0] c2l,
+ input [DATA_WIDTH-1:0] c1h,
+ input [DATA_WIDTH-1:0] c1m,
+ input [DATA_WIDTH-1:0] c1l,
+
+ output [DATA_WIDTH-1:0] median
+);
+
+ wire [DATA_WIDTH-1:0] node_u0_lo;
+ wire [DATA_WIDTH-1:0] node_u1_hi;
+ wire [DATA_WIDTH-1:0] node_u1_lo;
+ wire [DATA_WIDTH-1:0] node_u2_hi;
+ wire [DATA_WIDTH-1:0] node_u3_lo;
+ wire [DATA_WIDTH-1:0] node_u4_hi;
+ wire [DATA_WIDTH-1:0] node_u5_hi;
+ wire [DATA_WIDTH-1:0] node_u6_lo;
+ wire [DATA_WIDTH-1:0] node_u7_hi;
+ wire [DATA_WIDTH-1:0] node_u7_lo;
+ wire [DATA_WIDTH-1:0] node_u8_hi;
+
+ node
+ #(
+ .DATA_WIDTH(DATA_WIDTH),
+ .LOW_MUX(1), // disable low output
+ .HI_MUX(0) // disable hight output
+ ) node_u0 (
+ .data_a(c3h),
+ .data_b(c2h),
+
+ // .data_hi(),
+ .data_lo(node_u0_lo)
+ );
+
+ node
+ #(
+ .DATA_WIDTH(DATA_WIDTH),
+ .LOW_MUX(1), // disable low output
+ .HI_MUX(1) // disable hight output
+ ) node_u1 (
+ .data_a(c3m),
+ .data_b(c2m),
+
+ .data_hi(node_u1_hi),
+ .data_lo(node_u1_lo)
+ );
+
+ node
+ #(
+ .DATA_WIDTH(DATA_WIDTH),
+ .LOW_MUX(0), // disable low output
+ .HI_MUX(1) // disable hight output
+ ) node_u2 (
+ .data_a(c2l),
+ .data_b(c1l),
+
+ .data_hi(node_u2_hi)
+ // .data_lo()
+ );
+
+ node
+ #(
+ .DATA_WIDTH(DATA_WIDTH),
+ .LOW_MUX(1), // disable low output
+ .HI_MUX(0) // disable hight output
+ ) node_u3 (
+ .data_a(node_u0_lo),
+ .data_b(c1h),
+
+ // .data_hi(),
+ .data_lo(node_u3_lo)
+ );
+ node
+ #(
+ .DATA_WIDTH(DATA_WIDTH),
+ .LOW_MUX(0), // disable low output
+ .HI_MUX(1) // disable hight output
+ ) node_u4 (
+ .data_a(node_u1_lo),
+ .data_b(c1m),
+
+ .data_hi(node_u4_hi)
+ // .data_lo()
+ );
+ node
+ #(
+ .DATA_WIDTH(DATA_WIDTH),
+ .LOW_MUX(0), // disable low output
+ .HI_MUX(1) // disable hight output
+ ) node_u5 (
+ .data_a(c3l),
+ .data_b(node_u2_hi),
+
+ .data_hi(node_u5_hi)
+ // .data_lo()
+ );
+
+ node
+ #(
+ .DATA_WIDTH(DATA_WIDTH),
+ .LOW_MUX(1), // disable low output
+ .HI_MUX(0) // disable hight output
+ ) node_u6 (
+ .data_a(node_u1_hi),
+ .data_b(node_u4_hi),
+
+ // .data_hi(),
+ .data_lo(node_u6_lo)
+ );
+
+ node
+ #(
+ .DATA_WIDTH(DATA_WIDTH),
+ .LOW_MUX(1), // disable low output
+ .HI_MUX(1) // disable hight output
+ ) node_u7 (
+ .data_a(node_u3_lo),
+ .data_b(node_u6_lo),
+
+ .data_hi(node_u7_hi),
+ .data_lo(node_u7_lo)
+ );
+
+ node
+ #(
+ .DATA_WIDTH(DATA_WIDTH),
+ .LOW_MUX(0), // disable low output
+ .HI_MUX(1) // disable hight output
+ ) node_u8 (
+ .data_a(node_u7_lo),
+ .data_b(node_u5_hi),
+
+ .data_hi(node_u8_hi)
+ // .data_lo()
+ );
+
+ node
+ #(
+ .DATA_WIDTH(DATA_WIDTH),
+ .LOW_MUX(1), // disable low output
+ .HI_MUX(0) // disable hight output
+ ) node_u9 (
+ .data_a(node_u7_hi),
+ .data_b(node_u8_hi),
+
+ // .data_hi(),
+ .data_lo(median)
+ );
+
+endmodule
\ No newline at end of file
Index: fpga-median/trunk/doc/memory_organization_example.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/pdf
Index: fpga-median/trunk/doc/memory_organization_example.pdf
===================================================================
--- fpga-median/trunk/doc/memory_organization_example.pdf (nonexistent)
+++ fpga-median/trunk/doc/memory_organization_example.pdf (revision 2)
fpga-median/trunk/doc/memory_organization_example.pdf
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Index: fpga-median/trunk/doc/AN FPGA-BASED IMPLEMENTATION FOR MEDIAN FILTER MEETING THE REAL-TIME REQUIREMENTS OF AUTOMATED VISUAL INSPECTION SYSTEMS.pdf
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/pdf
Index: fpga-median/trunk/doc/AN FPGA-BASED IMPLEMENTATION FOR MEDIAN FILTER MEETING THE REAL-TIME REQUIREMENTS OF AUTOMATED VISUAL INSPECTION SYSTEMS.pdf
===================================================================
--- fpga-median/trunk/doc/AN FPGA-BASED IMPLEMENTATION FOR MEDIAN FILTER MEETING THE REAL-TIME REQUIREMENTS OF AUTOMATED VISUAL INSPECTION SYSTEMS.pdf (nonexistent)
+++ fpga-median/trunk/doc/AN FPGA-BASED IMPLEMENTATION FOR MEDIAN FILTER MEETING THE REAL-TIME REQUIREMENTS OF AUTOMATED VISUAL INSPECTION SYSTEMS.pdf (revision 2)
fpga-median/trunk/doc/AN FPGA-BASED IMPLEMENTATION FOR MEDIAN FILTER MEETING THE REAL-TIME REQUIREMENTS OF AUTOMATED VISUAL INSPECTION SYSTEMS.pdf
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Index: fpga-median/trunk/sim/tb/dut_if.sv
===================================================================
--- fpga-median/trunk/sim/tb/dut_if.sv (nonexistent)
+++ fpga-median/trunk/sim/tb/dut_if.sv (revision 2)
@@ -0,0 +1,39 @@
+// +----------------------------------------------------------------------------
+// Universidade Federal da Bahia
+//------------------------------------------------------------------------------
+// PROJECT: FPGA Median Filter
+//------------------------------------------------------------------------------
+// FILE NAME : dut_if.sv
+// AUTHOR : Laue Rami Souza Costa de Jesus
+// -----------------------------------------------------------------------------
+
+interface dut_if (input bit clk);
+
+//input signals task
+
+logic rst_n;
+logic start;
+
+logic [7:0] pixel1;
+logic [7:0] pixel2;
+logic [7:0] pixel3;
+logic [7:0] pixel4;
+
+logic [31:0] word0;
+logic [31:0] word1;
+logic [31:0] word2;
+
+logic [9:0] waddr;
+logic [1:0] window_line_counter;
+
+//output signals task
+
+logic [31:0] ch_word0;
+logic [31:0] ch_word1;
+logic [31:0] ch_word2;
+
+logic end_of_operation;
+
+logic [7:0] result [0:51983];
+
+endinterface
fpga-median/trunk/sim/tb/dut_if.sv
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: fpga-median/trunk/sim/tb/driver.sv
===================================================================
--- fpga-median/trunk/sim/tb/driver.sv (nonexistent)
+++ fpga-median/trunk/sim/tb/driver.sv (revision 2)
@@ -0,0 +1,114 @@
+// +----------------------------------------------------------------------------
+// Universidade Federal da Bahia
+//------------------------------------------------------------------------------
+// PROJECT: FPGA Median Filter
+//------------------------------------------------------------------------------
+// FILE NAME : driver.sv
+// AUTHOR : Laue Rami Souza Costa de Jesus
+// -----------------------------------------------------------------------------
+class driver;
+
+// localparam MEMORY_WIDTH = 4331;
+ localparam NUM_PIXELS = (`IMG_WIDTH * `IMG_HEIGHT) - 1;//102400-1;
+
+ int cnt;
+ int addr;
+ int i;
+ logic [31:0] r_data_bram0;
+ logic [31:0] r_data_bram1;
+ logic [31:0] r_data_bram2;
+
+ logic [7:0] image [0:NUM_PIXELS];
+
+ virtual interface dut_if dut_if;
+
+ function new (virtual interface dut_if m_dut_if);
+ begin
+ dut_if = m_dut_if;
+ end
+ endfunction
+
+ task init();
+ begin
+ $display("RESET --------");
+ dut_if.rst_n = 1;
+ dut_if.start = 0;
+ dut_if.ch_word0 = 0;
+ dut_if.ch_word1 = 0;
+ dut_if.ch_word2 = 0;
+ addr = 0;
+ i = 0;
+ dut_if.end_of_operation = 0;
+ repeat(5)@(negedge dut_if.clk);
+ dut_if.rst_n = 0;
+ repeat(5)@(negedge dut_if.clk);
+ dut_if.rst_n = 1;
+ dut_if.start = 1;
+ repeat(3)@(negedge dut_if.clk);
+ end
+ endtask
+
+ task reorganize_lines();
+ begin
+ wait(dut_if.start);
+ @(negedge dut_if.clk);
+ while(!(dut_if.end_of_operation))begin
+ if(dut_if.window_line_counter == 2'b00)begin
+ dut_if.ch_word0 = dut_if.word0;
+ dut_if.ch_word1 = dut_if.word1;
+ dut_if.ch_word2 = dut_if.word2;
+ end
+ else if(dut_if.window_line_counter == 2'b01)begin
+ dut_if.ch_word0 = dut_if.word1;
+ dut_if.ch_word1 = dut_if.word2;
+ dut_if.ch_word2 = dut_if.word0;
+ end
+ else if(dut_if.window_line_counter == 2'b10)begin
+ dut_if.ch_word0 = dut_if.word2;
+ dut_if.ch_word1 = dut_if.word0;
+ dut_if.ch_word2 = dut_if.word1;
+ end
+ //addr = addr+1;
+ //read 4 pixels from all memories
+ @(negedge dut_if.clk);
+ end
+ dut_if.start = 0;
+ end
+ endtask
+
+ task receive_data();
+ fork begin
+ while(i
fpga-median/trunk/sim/tb/driver.sv
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: fpga-median/trunk/sim/tb/median_tb.v
===================================================================
--- fpga-median/trunk/sim/tb/median_tb.v (nonexistent)
+++ fpga-median/trunk/sim/tb/median_tb.v (revision 2)
@@ -0,0 +1,104 @@
+// +----------------------------------------------------------------------------
+// Universidade Federal da Bahia
+//------------------------------------------------------------------------------
+// PROJECT: FPGA Median Filter
+//------------------------------------------------------------------------------
+// FILE NAME : median_tb.v
+// AUTHOR : João Carlos Bittencourt
+// AUTHOR'S E-MAIL : joaocarlos@ieee.org
+// -----------------------------------------------------------------------------
+// RELEASE HISTORY
+// VERSION DATE AUTHOR DESCRIPTION
+// 1.0 2013-08-27 joao.nunes initial version
+// -----------------------------------------------------------------------------
+// KEYWORDS: median, filter, image processing
+// -----------------------------------------------------------------------------
+// PURPOSE: Testbench for Median filter.
+// -----------------------------------------------------------------------------
+module median_tb;
+
+ localparam PERIOD = 10;
+ localparam PIXEL_DATA_WIDTH = 8;
+ localparam LUT_ADDR_WIDTH = 10; // Input LUTs
+ localparam MEM_ADDR_WIDTH = 10; // Output Memory
+
+ reg clk;
+ reg rst_n;
+ always #(PERIOD/2) clk = ~clk;
+
+ reg [(PIXEL_DATA_WIDTH*4)-1:0] word0;
+ reg [(PIXEL_DATA_WIDTH*4)-1:0] word1;
+ reg [(PIXEL_DATA_WIDTH*4)-1:0] word2;
+
+ wire [PIXEL_DATA_WIDTH-1:0] pixel1;
+ wire [PIXEL_DATA_WIDTH-1:0] pixel2;
+ wire [PIXEL_DATA_WIDTH-1:0] pixel3;
+ wire [PIXEL_DATA_WIDTH-1:0] pixel4;
+
+ wire [9:0] raddr_a;
+ wire [9:0] raddr_b;
+ wire [9:0] raddr_c;
+
+ wire [9:0] waddr;
+
+ median
+ #(
+ .MEM_DATA_WIDTH(PIXEL_DATA_WIDTH*4),
+ .PIXEL_DATA_WIDTH(PIXEL_DATA_WIDTH),
+ .LUT_ADDR_WIDTH(LUT_ADDR_WIDTH),
+ .MEM_ADDR_WIDTH(MEM_ADDR_WIDTH)
+ ) dut_u0 (
+ .clk(clk), // Clock
+ .rst_n(rst_n), // Asynchronous reset active low
+
+ .word0(word0),
+ .word1(word1),
+ .word2(word2),
+
+ .pixel1(pixel1),
+ .pixel2(pixel2),
+ .pixel3(pixel3),
+ .pixel4(pixel4),
+ .raddr_a(raddr_a),
+ .raddr_b(raddr_b),
+ .raddr_c(raddr_c),
+
+ .waddr(waddr)
+ );
+
+ initial begin
+ clk = 1;
+ rst_n = 0;
+ word0 = 0;
+ word1 = 0;
+ word2 = 0;
+ #(PERIOD*3)
+ rst_n = 1;
+ word0 = {8'd160,8'd171,8'd164,8'd142};
+ word1 = {8'd123,8'd141,8'd149,8'd154};
+ word2 = {8'd163,8'd177,8'd171,8'd136};
+ #PERIOD
+ word0 = {8'd167,8'd193,8'd171,8'd160};
+ word1 = {8'd174,8'd150,8'd123,8'd166};
+ word2 = {8'd142,8'd165,8'd162,8'd171};
+ #PERIOD
+ word0 = {8'd168,8'd179,8'd146,8'd173};
+ word1 = {8'd171,8'd160,8'd152,8'd154};
+ word2 = {8'd156,8'd142,8'd147,8'd167};
+ #PERIOD
+ word0 = {8'd123,8'd141,8'd149,8'd154};
+ word1 = {8'd163,8'd177,8'd171,8'd136};
+ word2 = {8'd204,8'd151,8'd140,8'd140};
+ #PERIOD
+ word0 = {8'd174,8'd150,8'd123,8'd166};
+ word1 = {8'd142,8'd165,8'd162,8'd171};
+ word2 = {8'd142,8'd158,8'd149,8'd128};
+ #PERIOD
+ word0 = {8'd171,8'd160,8'd152,8'd154};
+ word1 = {8'd156,8'd142,8'd147,8'd167};
+ word2 = {8'd159,8'd128,8'd131,8'd160};
+ repeat (100) @(negedge clk);
+ $stop;
+ end
+
+endmodule
\ No newline at end of file
Index: fpga-median/trunk/sim/tb/median_tb_directed.sv
===================================================================
--- fpga-median/trunk/sim/tb/median_tb_directed.sv (nonexistent)
+++ fpga-median/trunk/sim/tb/median_tb_directed.sv (revision 2)
@@ -0,0 +1,151 @@
+// +----------------------------------------------------------------------------
+// Universidade Federal da Bahia
+//------------------------------------------------------------------------------
+// PROJECT: FPGA Median Filter
+//------------------------------------------------------------------------------
+// FILE NAME : median_tb.v
+// AUTHOR : João Carlos Bittencourt
+// AUTHOR'S E-MAIL : joaocarlos@ieee.org
+// -----------------------------------------------------------------------------
+// RELEASE HISTORY
+// VERSION DATE AUTHOR DESCRIPTION
+// 1.0 2013-08-27 joao.nunes initial version
+// 1.1 2013-09-04 laue.rami modified version
+// -----------------------------------------------------------------------------
+// KEYWORDS: median, filter, image processing
+// -----------------------------------------------------------------------------
+// PURPOSE: Testbench for Median filter.
+// -----------------------------------------------------------------------------
+`define IMG_HEIGHT 'd320
+`define IMG_WIDTH 'd320
+module median_tb;
+
+ `include "../tb/driver.sv"
+
+ driver driver_u0;
+
+ localparam PERIOD = 10;
+ localparam PIXEL_DATA_WIDTH = 8;
+ localparam LUT_ADDR_WIDTH = 14; // Input LUTs
+ localparam MEM_ADDR_WIDTH = 14; // Output Memory
+
+ bit clk;
+
+ wire [MEM_ADDR_WIDTH-1:0] raddr_a;
+ wire [MEM_ADDR_WIDTH-1:0] raddr_b;
+ wire [MEM_ADDR_WIDTH-1:0] raddr_c;
+ wire [MEM_ADDR_WIDTH-1:0] waddr_a;
+ wire [MEM_ADDR_WIDTH-1:0] waddr_b;
+ wire [MEM_ADDR_WIDTH-1:0] waddr_c;
+
+
+ wire [MEM_ADDR_WIDTH-1:0] waddr;
+
+ reg [(PIXEL_DATA_WIDTH*4)-1:0] word0;
+ reg [(PIXEL_DATA_WIDTH*4)-1:0] word1;
+ reg [(PIXEL_DATA_WIDTH*4)-1:0] word2;
+
+ wire [31:0] w_data_bram0;
+ wire [31:0] w_data_bram1;
+ wire [31:0] w_data_bram2;
+
+ //dut_if interface
+ dut_if dut_if (clk);
+
+ //driver
+
+ always #(PERIOD/2) clk = ~clk;
+
+ dual_port_ram
+ #(
+ .MEMFILE("./memA.hex"),
+ .DATA_WIDTH('d32),
+ .ADDR_WIDTH('d14)
+ )
+ BRAM0
+ (
+ .clk(clk),
+ .r_ena(1'b1),
+ .w_ena(1'b0),
+ .w_data(w_data_bram0),
+ .w_addr(waddr_a),
+ .r_addr(raddr_a),
+ .r_data(dut_if.word0)
+ );
+
+ dual_port_ram
+ #(
+ .MEMFILE("./memB.hex"),
+ .DATA_WIDTH('d32),
+ .ADDR_WIDTH('d14)
+ )
+ BRAM1
+ (
+ .clk(clk),
+ .r_ena(1'b1),
+ .w_ena(1'b0),
+ .w_data(w_data_bram1),
+ .w_addr(waddr_b),
+ .r_addr(raddr_b),
+ .r_data(dut_if.word1)
+ );
+
+ dual_port_ram
+ #(
+ .MEMFILE("./memC.hex"),
+ .DATA_WIDTH('d32),
+ .ADDR_WIDTH('d14)
+ )
+ BRAM2
+ (
+ .clk(clk),
+ .r_ena(1'b1),
+ .w_ena(1'b0),
+ .w_data(w_data_bram2),
+ .w_addr(waddr_c),
+ .r_addr(raddr_c),
+ .r_data(dut_if.word2)
+ );
+
+ median
+ #(
+ .MEM_DATA_WIDTH(PIXEL_DATA_WIDTH*4),
+ .PIXEL_DATA_WIDTH(PIXEL_DATA_WIDTH),
+ .LUT_ADDR_WIDTH(LUT_ADDR_WIDTH),
+ .MEM_ADDR_WIDTH(MEM_ADDR_WIDTH),
+ .IMG_WIDTH(`IMG_WIDTH),
+ .IMG_HEIGHT(`IMG_HEIGHT)
+ ) dut_u0 (
+ .clk(clk), // Clock
+ .rst_n(dut_if.rst_n), // Asynchronous reset active low
+ .word0(dut_if.ch_word0),
+ .word1(dut_if.ch_word1),
+ .word2(dut_if.ch_word2),
+ .pixel1(dut_if.pixel1),
+ .pixel2(dut_if.pixel2),
+ .pixel3(dut_if.pixel3),
+ .pixel4(dut_if.pixel4),
+ .raddr_a(raddr_a),
+ .raddr_b(raddr_b),
+ .raddr_c(raddr_c),
+ .waddr(dut_if.waddr)
+ );
+
+ always@(*)begin
+ dut_if.window_line_counter = dut_u0.window_contol.window_line_counter;
+ end
+
+ initial begin
+ $display("INICIO -------");
+ driver_u0 = new(dut_if);
+ driver_u0.init();
+ driver_u0.receive_data();
+ driver_u0.reorganize_lines();
+ wait(dut_if.end_of_operation);
+ driver_u0.write_file();
+ #(PERIOD*3)
+ repeat(100)@(negedge clk);
+ $stop;
+ end
+
+endmodule
fpga-median/trunk/sim/tb/median_tb_directed.sv
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: fpga-median/trunk/software/median_ref.m
===================================================================
--- fpga-median/trunk/software/median_ref.m (nonexistent)
+++ fpga-median/trunk/software/median_ref.m (revision 2)
@@ -0,0 +1,65 @@
+% +----------------------------------------------------------------------------
+% Universidade Federal da Bahia
+% ------------------------------------------------------------------------------
+% PROJECT: FPGA Median Filter
+% ------------------------------------------------------------------------------
+% FILE NAME : median_ref.m
+% AUTHOR : João Carlos Bittencourt
+% AUTHOR'S E-MAIL : joaocarlos@ieee.org
+% -----------------------------------------------------------------------------
+% RELEASE HISTORY
+% VERSION DATE AUTHOR DESCRIPTION
+% 1.0 2013-08-27 joao.nunes initial version
+% -----------------------------------------------------------------------------
+% KEYWORDS: median, filter, image processing
+% -----------------------------------------------------------------------------
+% PURPOSE: Reference model for Median Filter.
+% -----------------------------------------------------------------------------
+
+% This is only a simple verification reference model based on default Median Filter
+
+% Clear environment
+clc
+clear
+% Set-up vectors
+% I have set the vector to size 12 in order to perform a basic testbench.
+% result = zeros(227,227);
+img_ref = imread('images/image22.jpg');
+
+img_ref = rgb2gray(img_ref);
+[width, height] = size(img_ref);
+% Add one column with zeros for pipelining verification purpose.
+% The hardware assumes that, in the first round in a row, previous values are zeros.
+img = zeros(width+1,width+1);
+for i = 1 : height,
+ img(i,2:width+1) = img_ref(i, 1:width);
+end
+
+
+% Default Median Algorithm
+window_width = 3;
+window_height = 3;
+edgex = floor(window_width/2);
+edgey = floor(window_height/2);
+tic
+for x = edgex : width - edgex,
+ for y = edgey : height - edgey,
+ temp = zeros(edgex,edgey);
+ for fx = 1 : window_width,
+ for fy = 1 : window_height,
+ temp(fx,fy) = img(x + fx - edgex, y + fy - edgey);
+ end
+ end
+ temp = reshape(temp.',1,[]);
+ srt = sort(temp); % remove comma to view step by step outputs
+ result(x,y) = srt(5);
+ end
+end
+toc
+wtime = toc
+fprintf ( 1, ' MY_PROGRAM took %f seconds to run.\n', wtime );
+
+%result
+imshow(mat2gray(result));
+imwrite(mat2gray(result), 'images/image22_median.jpg', 'jpg');
+
Index: fpga-median/trunk/software/generate_bram.m
===================================================================
--- fpga-median/trunk/software/generate_bram.m (nonexistent)
+++ fpga-median/trunk/software/generate_bram.m (revision 2)
@@ -0,0 +1,114 @@
+% +----------------------------------------------------------------------------
+% Universidade Federal da Bahia
+% ------------------------------------------------------------------------------
+% PROJECT: FPGA Median Filter
+% ------------------------------------------------------------------------------
+% FILE NAME : generate_bram.m
+% AUTHOR : João Carlos Bittencourt
+% AUTHOR'S E-MAIL : joaocarlos@ieee.org
+% -----------------------------------------------------------------------------
+% RELEASE HISTORY
+% VERSION DATE AUTHOR DESCRIPTION
+% 1.0 2013-09-02 laue.rami initial version
+% -----------------------------------------------------------------------------
+% KEYWORDS: median, filter, image processing
+% -----------------------------------------------------------------------------
+% PURPOSE: Convert an image into a 3 block memory to be used in RTL.
+% -----------------------------------------------------------------------------
+
+clear
+%read image
+a = imread('images/image55.jpg');
+%essa parte eh para deixar a imagem certinha 224x224
+tmp = size(a);
+lin = tmp(1,1);
+col = tmp(1,2);
+for i=1:lin-1
+ for j=1:col-1
+ a_mod(i,j) = a(i,j);
+ end
+end
+%obtain image size
+size_image = size(a_mod);
+%create colum zeros
+zero_coluna = zeros(size_image(1), 1);
+%junta coluna de zeros na esquerda
+left_edge = [zero_coluna a_mod];
+%junta coluna de zeros na direita
+both_edge = [left_edge zero_coluna];
+%obtain image size
+size_image = size(both_edge);
+%create line zeros
+zero_linha = zeros(1, size_image(2));
+%junta linha de zero na parte de cima
+up_edge = [zero_linha ; both_edge];
+%junta linha de zero na parte de baixo
+edge_image = [up_edge ; zero_linha];
+%guarda o numero de linhas e o numero de colunas
+temp = size(edge_image);
+num_linhas = temp(1,1);
+num_colunas = temp(1,2);
+%abre arquivo para salvar a memoria
+fileID_a = fopen('memA_hex.txt','w');
+fileID_b = fopen('memB_hex.txt','w');
+fileID_c = fopen('memC_hex.txt','w');
+%transposta da imagem
+new_image = edge_image.';
+%converte para hexadecimal
+image_hex = dec2hex(new_image);
+%obtain o tamanho da imagem
+aux = size(image_hex);
+%obtain numero de pixels
+num_pixels = aux(1,1);
+
+image_conv = reshape(edge_image.',320,[]);
+for i = 1 : size(image_conv)
+ image_hex(i) = dec2hex(image_conv(i));
+end
+
+for i = 1 : size(image_conv)
+ image_conv(i) = hex2dec(image_hex(i));
+end
+image = vec2mat(image_conv.',320);
+
+imshow(image);
+
+count = 1;
+
+acc = num_linhas*3;
+loops = num_pixels/acc;
+
+for m=1:loops
+
+ %para a memoria A - grava
+ for ma=1:(num_linhas/4)
+ for na=1:4
+ fprintf(fileID_a,'%s',image_hex(count,:));
+ count=count+1;
+ end
+ fprintf(fileID_a,'\n');
+ end
+
+ %para a memoria B - grava
+ for ma=1:(num_linhas/4)
+ for na=1:4
+ fprintf(fileID_b,'%s',image_hex(count,:));
+ count=count+1;
+ end
+ fprintf(fileID_b,'\n');
+ end
+
+ %para a memoria C - grava
+ for ma=1:(num_linhas/4)
+ for na=1:4
+ fprintf(fileID_c,'%s',image_hex(count,:));
+ count=count+1;
+ end
+ fprintf(fileID_c,'\n');
+ end
+end
+
+fclose(fileID_a);
+fclose(fileID_b);
+fclose(fileID_c);
+
Index: fpga-median/trunk/software/median_return.m
===================================================================
--- fpga-median/trunk/software/median_return.m (nonexistent)
+++ fpga-median/trunk/software/median_return.m (revision 2)
@@ -0,0 +1,32 @@
+clc
+clear
+
+id = fopen('image.hex', 'r');
+image_c = fscanf(id, '%d');
+
+%image = vec2mat(image_c, 866);
+%image = reshape(image_c,598,866);
+% image = reshape(image_c.',598,[]);
+
+image = zeros(227,227);
+k = 1;
+for i = 1 : 227
+ z = 0;
+ for j = 1 : 227
+ image(i,j) = hex2dec(image_c(k));
+ k = k + 1;
+ end
+end
+
+% for i = 1 : 510
+% for j = 1 : 510
+% if(image(i,j) == 255)
+% image(i,j) = 0;
+% else
+% image(i,j) = 1;
+% end
+% end
+% end
+
+imshow(image);
+% imwrite(image, 'return.jpg', 'jpg');
\ No newline at end of file
Index: fpga-median/trunk/software/convert_rtl.m
===================================================================
--- fpga-median/trunk/software/convert_rtl.m (nonexistent)
+++ fpga-median/trunk/software/convert_rtl.m (revision 2)
@@ -0,0 +1,50 @@
+% +----------------------------------------------------------------------------
+% Universidade Federal da Bahia
+% ------------------------------------------------------------------------------
+% PROJECT: FPGA Median Filter
+% ------------------------------------------------------------------------------
+% FILE NAME : convert_rtl.m
+% AUTHOR : João Carlos Bittencourt
+% AUTHOR'S E-MAIL : joaocarlos@ieee.org
+% -----------------------------------------------------------------------------
+% RELEASE HISTORY
+% VERSION DATE AUTHOR DESCRIPTION
+% 1.0 2013-08-27 joao.nunes initial version
+% 2.0 2013-09-03 laue.rami fix problem with vec2mat fucntion usage
+% -----------------------------------------------------------------------------
+% KEYWORDS: median, filter, image processing
+% -----------------------------------------------------------------------------
+% PURPOSE: Convert a RTL memory in an image matrix
+% -----------------------------------------------------------------------------
+
+clc
+clear
+
+id = fopen('image.hex','r');
+
+for i=1:102400 % vector width
+ image_rtl(i,1) = fscanf(id, '%c', 1);
+ image_rtl(i,2) = fscanf(id, '%c', 1);
+ lixo(1) = fscanf(id, '%c', 1);
+end
+
+
+% for i=1:51984
+% image(i) = hex2dec(image_rtl(i,:));
+% end
+var = hex2dec(image_rtl);
+
+count=1;
+for i=1:320 % height
+ for j=1:320 % width
+ foto(i,j)= var(count);
+ count=count+1;
+ end
+end
+foto = foto;
+% image = vec2mat(image,228);
+a = mat2gray(foto);
+imshow(mat2gray(foto));
+imwrite(a, 'image_transform.jpg', 'jpeg');
+
+fclose(id);
\ No newline at end of file