OpenCores
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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.