【发布时间】:2014-05-17 22:49:21
【问题描述】:
我一直在使用 verilog 尝试实现一个小的图像过滤器,它可以添加模糊效果、镜像图像或将其旋转 90*。我对这些东西很陌生,所以请多多包涵。 我在运行模拟时注意到寄存器在更改为新值之前有很大的延迟,到目前为止这给我带来了一些问题。我设法让镜像和旋转工作,然后添加了模糊滤镜。现在由于某些奇怪的原因它不再起作用了,即使在删除了新添加的代码之后也是如此。它一直向我显示输出是 X ... 我正在使用 64x64 灰度图像,并进行一些简单的矩阵运算。我似乎仍然无法正常工作,特别是模糊过滤器,现在我有这个神秘的所有输出都是 X,而在模拟模式下出于某种原因。
这是该过程的代码:
`timescale 1ns / 1ps
module process(
input clk, // clock
input [1:0] op, // 0 - filtrul de tip blur; 1 - oglindire; 2 - rotire
input [7:0] in_pix, // valaorea pixelului de pe pozitia [in_row, in_col] din imaginea de intrare
output reg [5:0] in_row, in_col, // selecteaza un rand si o coloana din imaginea de intrare
output reg [5:0] out_row, out_col, // selecteaza un rand si o coloana din imaginea de iesire
output reg out_we, // activeaza scrierea pentru imaginea de iesire (write enable)
output reg [7:0] out_pix, // valoarea pixelului care va fi scrisa in imaginea de iesire pe pozitia [out_row, out_col]
output reg done // semnaleaza cand s-a terminat procesarea unei imagini
);
// TODO add your finite state machines here
`define INIT 3'b000
`define MOVE_PIXEL 3'b001
`define INC_INDEX 3'b010
`define DONE 3'b011
`define DIVISION 3'b100
reg [6:0] index_col,index_row,index1_col,index1_row; // indicatori cu care se parcurg matricea imagine pentru input si output.
reg [2:0] state; // registru de stare pentru automate
reg [7:0] pixel; // registru in care stocam valoarea de pixel pentru intrare si iesire
reg [7:0] pixel_q; // registru folosit pentru memorarea catului la impartirea prin 5.
reg [10:0] sum; // folosit pentru insumarea pixelilor vecini dupa care este inmultita cu 0.2 pentru a face sum/5. este pe 11 biti deoarece 255*5 este 1275, deci 2^11 = 2048 ca sa nu avem overflow
reg [3:0] timer; // timer pentru sincronizarea datelor , am ales sa astept 6 ciclii pentru realizarea sincronizarii
always@(posedge clk) begin
/*if(op == 0) begin // Pentru marginile imaginii am decis sa fac cazuri speciale
state <= `INIT; // astfel adun doar elementele care exista langa pixelul curent
// de exemplu in coltul 0.0 avem elemente doar la 0.1 si 1.0.
case(state)
`INIT: begin
index_row <= 0;
index_col <= 0;
done <= 0;
timer <= 0;
pixel_q <= 0;
state <= `MOVE_PIXEL;
end
`MOVE_PIXEL: begin
sum <= 0;
in_row <= index_row;
in_col <= index_col;
pixel <= in_pix;
if(timer < 6) begin
timer <= timer + 1;
state <=`MOVE_PIXEL;
end else begin
sum <= sum + pixel;
if(index_row == 0 && index_col == 0) begin // cazuri speciale: colturile si marginile; coltul 0.0
in_row <= index_row + 1;
pixel <= in_pix;
sum <= sum + pixel;
in_row <= index_row - 1;
in_col <= index_col + 1;
pixel <= in_pix;
sum <= sum + pixel;
// sum <= sum * 0.2;
in_col <= index_col - 1;
state <= `DIVISION;
end else if (index_row == 0 && index_col == 63) begin // coltul 0.63
in_row <= index_row + 1;
pixel <= in_pix;
sum <= sum + pixel;
in_row <= index_row - 1;
in_col <= index_col - 1;
pixel <= in_pix;
sum <= sum + pixel;
// sum <= sum * 0.2;
in_col <= index_col + 1;
state <= `DIVISION;
end else if(index_row == 63 && index_col == 0) begin //coltul 63.0
in_row <= index_row - 1;
pixel <= in_pix;
sum <= sum + pixel;
in_row <= index_row + 1;
in_col <= index_col + 1;
pixel <= in_pix;
sum <= sum + pixel;
// sum <= sum * 0.2;
in_col <= index_col - 1;
state <= `DIVISION;
end else if(index_row == 63 && index_col == 63) begin // coltul 63.63
in_row <= index_row - 1;
pixel <= in_pix;
sum <= sum + pixel;
in_row <= index_row + 1;
in_col <= index_col - 1;
pixel <= in_pix;
sum <= sum + pixel;
// sum <= sum * 0.2;
in_col <= index_col + 1;
state <= `DIVISION;
end else if(in_row == 0 && in_col > 0) begin // marginea de sus
in_row <= index_row + 1;
pixel <= in_pix;
sum <= sum + pixel;
in_row <= index_row - 1;
in_col <= index_col + 1;
pixel <= in_pix;
sum <= sum + pixel;
in_col <= index_col - 2;
pixel <= in_pix;
sum <= sum + pixel;
// sum <= sum * 0.2;
in_col <= index_col + 1;
state <= `DIVISION;
end else if(in_col == 0 && in_row > 0) begin // marginea din stanga
in_row <= index_row + 1;
pixel <= in_pix;
sum <= sum + pixel;
in_row <= index_row - 1;
in_col <= index_col + 1;
pixel <= in_pix;
sum <= sum + pixel;
in_col <= index_col - 1;
in_row <= index_row - 1;
pixel <= in_pix;
sum <= sum + pixel;
// sum <= sum * 0.2;
in_col <= index_row + 1;
state <= `DIVISION;
end else if(in_row == 63 && in_col > 0) begin //marginea de jos
in_row <= index_row - 1;
pixel <= in_pix;
sum <= sum + pixel;
in_row <= index_row + 1;
in_col <= index_col + 1;
pixel <= in_pix;
sum <= sum + pixel;
in_col <= index_col - 2;
pixel <= in_pix;
sum <= sum + pixel;
// sum <= sum * 0.2;
in_col <= index_col + 1;
state <= `DIVISION;
end else if(in_col == 63 && in_row > 0) begin // marginea din dreapta
in_row <= index_row + 1;
pixel <= in_pix;
sum <= sum + pixel;
in_row <= index_row - 1;
in_col <= index_col - 1;
pixel <= in_pix;
sum <= sum + pixel;
in_col <= index_col + 1;
in_row <= index_row - 1;
pixel <= in_pix;
sum <= sum + pixel;
// sum <= sum * 0.2;
in_col <= index_row + 1;
state <= `DIVISION;
end else begin //interiorul matricii // 0 (index_row -1).index_col 0
in_row <= index_row + 1; // index_row.(index_col - 1) index_row.index_col index_row.(index_col + 1)
pixel <= in_pix; // 0 (index_row + 1).index_col 0
sum <= sum + pixel; // Structura in care sunt alesi pixelii pentru blur.
in_row <= index_row - 1;
in_col <= index_col - 1;
pixel <= in_pix;
sum <= sum + pixel;
in_col <= index_col + 1;
in_row <= index_row - 1;
pixel <= in_pix;
sum <= sum + pixel;
in_col <= index_col + 1;
in_row <= index_row - 1;
pixel <= in_pix;
sum <= sum + in_pix;
// sum <= sum * 0.2;
in_col <= index_col - 1;
state <= `DIVISION;
out_row <= index_row;
out_col <= index_col;
out_we <= 1;
out_pix <= pixel;
state <= `INC_INDEX;
end
end
end
`DIVISION: begin
if(sum >= 5) begin
sum <= sum - 5;
pixel_q <= pixel_q + 1;
state <= `DIVISION;
end else begin
out_row <= index_row;
out_col <= index_col;
out_we <= 1;
out_pix <= pixel_q;
state <= `INC_INDEX;
end
end
`INC_INDEX: begin
index_col <= index_col + 1;
if( index_col == 63 ) begin
index_row <= index_row + 1;
state <= `MOVE_PIXEL;
end else if (index_row == 63 && index1_row == 63) begin
state <= `DONE;
end else begin
state <= `MOVE_PIXEL;
end
end
`DONE: begin
done <= 1;
state <= `INIT;
end
endcase
end */
if(op == 1) begin // pixelii sunt inversati ca pozitie, pixelii din prima coloana trec in ultima si invers, procedeul se repeta secvential.
state <= `INIT;
case(state)
`INIT: begin
index_row <= 0;
index_col <= 0;
index1_row <= 0;
index1_col <= 63;
// timer <= 0;
done <= 0;
state <= `MOVE_PIXEL;
end
`MOVE_PIXEL: begin
in_row <= index1_row;
in_col <= index1_col;
pixel <= in_pix;
// if(timer < 6) begin
// timer <= timer + 1;
// state <=`MOVE_PIXEL;
// end else begin
out_row <= index_row;
out_col <= index_col;
out_we <= 1;
out_pix <= pixel;
out_we <= 0;
state <= `INC_INDEX;
// end
end
`INC_INDEX: begin
index_col <= index_col + 1;
index1_col <= index1_col - 1;
if( index_col == 63 && index1_col == 0) begin
index_row <= index_row + 1;
index1_row <= index1_row +1;
state <= `MOVE_PIXEL;
end else if (index_row == 63 && index1_row == 63) begin
state <= `DONE;
end else begin
state <= `MOVE_PIXEL;
end
end
`DONE: begin
done <= 1;
state <= `INIT;
end
endcase
end
if(op == 2) begin // liniile devine coloane, se incepe de la ultima linie care se scrie ca prima coloana si se repeta procedeul.
state <= `INIT;
case(state)
`INIT: begin
index_row <= 0;
index_col <= 0;
index1_row <= 63;
index1_col <= 0;
// timer <= 0;
done <= 0;
state <= `MOVE_PIXEL;
end
`MOVE_PIXEL: begin
in_row <= index1_row;
in_col <= index1_col;
pixel <= in_pix;
// if(timer < 6) begin
// timer <= timer + 1;
// state <=`MOVE_PIXEL;
// end else begin
out_row <= index_row;
out_col <= index_col;
out_we <= 1;
out_pix <= pixel;
out_we <= 0;
state <= `INC_INDEX;
// end
end
`INC_INDEX: begin
index_row <= index_row + 1;
index1_col <= index1_col + 1;
if( index_row == 63 && index1_col == 63) begin
index_col <= index_col + 1;
index1_row <= index1_row - 1;
state <= `MOVE_PIXEL;
end else if (index_col == 63 && index1_row == 0) begin
state <= `DONE;
end else begin
state <= `MOVE_PIXEL;
end
end
`DONE: begin
done <= 1;
state <= `INIT;
end
endcase
end
end
endmodule
它与图像模块交互:
`timescale 1ns / 1ps
module image(
input clk, // clock
input[5:0] row, // selecteaza un rand din imagine
input[5:0] col, // selecteaza o coloana din imagine
input we, // write enable (activeaza scrierea in imagine la randul si coloana date)
input[7:0] in, // valoarea pixelului care va fi scris pe pozitia data
output[7:0] out // valoarea pixelului care va fi citit de pe pozitia data
);
reg[7:0] data[63:0][63:0];
assign out = data[row][col];
always @(posedge clk) begin
if(we)
data[row][col] <= in;
end
endmodule
有人可以帮我吗?如果我的问题格式不正确,我深表歉意,这是第一次在这里发布。
LE:我重新设计了模糊滤镜的状态机,但我收到了一些奇怪的警告。例如,它说 Timer_3(我假设它在谈论来自处理旋转的第三个 FSM 的计时器)“FF/Latch(没有初始值)在块中具有恒定值 0。这个 FF/Latch 将在优化过程中被修剪。” 而这个也是“信号被分配但从未使用过。这个未连接的信号将在优化过程中被修剪。”没看懂怎么没用?我清楚地用它去 INIT_BLUR 并从那里去 CURRENT_PIXEL。
`timescale 1ns / 1ps
module process(
input clk, // clock
input [1:0] op, // 0 - filtrul de tip blur; 1 - oglindire; 2 - rotire
input [7:0] in_pix, // valaorea pixelului de pe pozitia [in_row, in_col] din imaginea de intrare
output reg [5:0] in_row, in_col, // selecteaza un rand si o coloana din imaginea de intrare
output reg [5:0] out_row, out_col, // selecteaza un rand si o coloana din imaginea de iesire
output reg out_we, // activeaza scrierea pentru imaginea de iesire (write enable)
output reg [7:0] out_pix, // valoarea pixelului care va fi scrisa in imaginea de iesire pe pozitia [out_row, out_col]
output reg done // semnaleaza cand s-a terminat procesarea unei imagini
);
// TODO add your finite state machines here
`define INIT_BLUR 4'b0000
`define CURRENT_PIXEL 4'b0001
`define TOP_PIXEL 4'b0010
`define BOTTOM_PIXEL 4'b0011
`define LEFT_PIXEL 4'b0100
`define RIGHT_PIXEL 4'b0101
`define DIVISION 4'b0110
`define INC_INDEX_BLUR 4'b0111
`define DONE_BLUR 4'b1000
`define INIT 3'b000
`define MOVE_PIXEL 3'b001
`define INC_INDEX 3'b010
`define DONE 3'b011
reg [6:0] index_col,index_row,index1_col,index1_row; // indicatori cu care se parcurg matricea imagine pentru input si output.
reg [2:0] state; // registru de stare pentru automate
reg [3:0] blur_states;
reg [7:0] pixel; // registru in care stocam valoarea de pixel pentru intrare si iesire
reg [7:0] pixel_q; // registru folosit pentru memorarea catului la impartirea prin 5.
reg [10:0] sum; // folosit pentru insumarea pixelilor vecini dupa care este inmultita cu 0.2 pentru a face sum/5. este pe 11 biti deoarece 255*5 este 1275, deci 2^11 = 2048 ca sa nu avem overflow
reg [3:0] timer; // timer pentru sincronizarea datelor , am ales sa astept 6 ciclii pentru realizarea sincronizarii
always@(posedge clk) begin
if(op == 0) begin // Pentru marginile imaginii am decis sa fac cazuri speciale
blur_states <= `INIT_BLUR; // astfel adun doar elementele care exista langa pixelul curent
// de exemplu in coltul 0.0 avem elemente doar la 0.1 si 1.0.
case(state)
`INIT_BLUR: begin
index_row <= 0;
index_col <= 0;
index1_row <= 0;
index1_col <= 0;
done <= 0;
timer <= 0;
pixel_q <= 0;
state <= `CURRENT_PIXEL;
end
`CURRENT_PIXEL: begin
sum <= 0;
in_row <= index_row;
in_col <= index_col;
pixel <= in_pix;
sum <= sum + pixel;
if(timer < 6) begin
timer <= timer + 1;
state <=`CURRENT_PIXEL;
end else begin
if(index_row == 0 && index_col == 0) begin // cazuri speciale: colturile si marginile; coltul 0.0
blur_states <= `RIGHT_PIXEL;
end else if (index_row == 0 && index_col == 63) begin // coltul 0.63
blur_states <= `BOTTOM_PIXEL;
end else if(in_row == 0 && in_col > 0) begin // marginea de sus
blur_states <= `RIGHT_PIXEL;
end else begin //interiorul matricii
blur_states <= `TOP_PIXEL;
// 0 (index_row -1).index_col 0
// in_row <= index_row + 1; // index_row.(index_col - 1) index_row.index_col index_row.(index_col + 1)
// pixel <= in_pix; // 0 (index_row + 1).index_col 0
// sum <= sum + pixel; // Structura in care sunt alesi pixelii pentru blur.
// in_row <= index_row - 1;
// in_col <= index_col - 1;
// pixel <= in_pix;
// sum <= sum + pixel;
// in_col <= index_col + 1;
// in_row <= index_row - 1;
// pixel <= in_pix;
// sum <= sum + pixel;
// in_col <= index_col + 1;
// in_row <= index_row - 1;
// pixel <= in_pix;
// sum <= sum + in_pix;
// sum <= sum * 0.2;
// in_col <= index_col - 1;
// state <= `DIVISION;
/*
out_row <= index_row;
out_col <= index_col;
out_we <= 1;
out_pix <= pixel;
state <= `INC_INDEX; */
end
end
end
`TOP_PIXEL: begin
index1_row <= index_row + 1;
index1_col <= index_col;
pixel <= in_pix;
sum <= sum + pixel;
if( index_col == 63 && index_row == 63) begin
blur_states <= `LEFT_PIXEL;
end else if( index_col == 63) begin
blur_states <= `BOTTOM_PIXEL;
end else begin
blur_states <= `RIGHT_PIXEL;
end
end
`RIGHT_PIXEL: begin
index1_row <= index_row;
index1_col <= index_col + 1;
pixel <= in_pix;
sum <= sum + pixel;
if( index_row == 63 && index_col == 0) begin
blur_states <= `DIVISION;
end else if(index_row == 63) begin
blur_states <= `LEFT_PIXEL;
end else begin
blur_states <= `BOTTOM_PIXEL;
end
end
`BOTTOM_PIXEL: begin
index1_row <= index_row - 1;
index1_col <= index_col;
pixel <= in_pix;
sum <= sum + pixel;
if (index_col == 0) begin
blur_states <= `DIVISION;
end else begin
blur_states <= `LEFT_PIXEL;
end
end
`LEFT_PIXEL: begin
index1_row <= index_row;
index1_col <= index_col - 1;
pixel <= in_pix;
sum <= sum + pixel;
blur_states<= `DIVISION;
end
`DIVISION: begin
if(sum >= 5) begin
sum <= sum - 5;
pixel_q <= pixel_q + 1;
state <= `DIVISION;
end else begin
out_row <= index_row;
out_col <= index_col;
out_we <= 1;
out_pix <= pixel_q;
state <= `INC_INDEX;
end
end
`INC_INDEX_BLUR: begin
out_we <= 0;
index_col <= index_col + 1;
if( index_col == 63 ) begin
index_row <= index_row + 1;
state <= `MOVE_PIXEL;
end else if (index_row == 63 && index1_row == 63) begin
state <= `DONE;
end else begin
state <= `MOVE_PIXEL;
end
end
`DONE_BLUR: begin
done <= 1;
state <= `INIT_BLUR;
end
endcase
end
if(op == 1) begin // pixelii sunt inversati ca pozitie, pixelii din prima coloana trec in ultima si invers, procedeul se repeta secvential.
state <= `INIT;
case(state)
`INIT: begin
index_row <= 0;
index_col <= 0;
index1_row <= 0;
index1_col <= 63;
timer <= 0;
done <= 0;
state <= `MOVE_PIXEL;
end
`MOVE_PIXEL: begin
in_row <= index1_row;
in_col <= index1_col;
pixel <= in_pix;
if(timer < 6) begin
timer <= timer + 1;
state <=`MOVE_PIXEL;
end else begin
out_row <= index_row;
out_col <= index_col;
out_we <= 1;
out_pix <= pixel;
out_we <= 0;
state <= `INC_INDEX;
end
end
`INC_INDEX: begin
index_col <= index_col + 1;
index1_col <= index1_col - 1;
if( index_col == 63 && index1_col == 0) begin
index_row <= index_row + 1;
index1_row <= index1_row +1;
state <= `MOVE_PIXEL;
end else if (index_row == 63 && index1_row == 63) begin
state <= `DONE;
end else begin
state <= `MOVE_PIXEL;
end
end
`DONE: begin
done <= 1;
state <= `INIT;
end
endcase
end
if(op == 2) begin // liniile devine coloane, se incepe de la ultima linie care se scrie ca prima coloana si se repeta procedeul.
state <= `INIT;
case(state)
`INIT: begin
index_row <= 0;
index_col <= 0;
index1_row <= 63;
index1_col <= 0;
timer <= 0;
done <= 0;
state <= `MOVE_PIXEL;
end
`MOVE_PIXEL: begin
in_row <= index1_row;
in_col <= index1_col;
pixel <= in_pix;
if(timer < 6) begin
timer <= timer + 1;
state <=`MOVE_PIXEL;
end else begin
out_row <= index_row;
out_col <= index_col;
out_we <= 1;
out_pix <= pixel;
out_we <= 0;
state <= `INC_INDEX;
end
end
`INC_INDEX: begin
index_row <= index_row + 1;
index1_col <= index1_col + 1;
if( index_row == 63 && index1_col == 63) begin
index_col <= index_col + 1;
index1_row <= index1_row - 1;
state <= `MOVE_PIXEL;
end else if (index_col == 63 && index1_row == 0) begin
state <= `DONE;
end else begin
state <= `MOVE_PIXEL;
end
end
`DONE: begin
done <= 1;
state <= `INIT;
end
endcase
end
end
endmodule
【问题讨论】:
标签: verilog