|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
- `timescale 1ns / 1ps
- //////////////////////////////////////////////////////////////////////////////////
- // Company:
- // Engineer:
- //
- // Create Date: 09:17:24 07/31/2016
- // Design Name: wuzhicheng
- // Module Name: datacut
- // Project Name:
- // Target Devices:
- // Tool versions:
- // Description:
- //
- // Dependencies: 从视频源中截取128X160像素点,假设就按从起始点截取。
- //
- // Revision:
- // Revision 0.01 - File Created
- // Additional Comments:
- //
- //////////////////////////////////////////////////////////////////////////////////
- module data_cut(
- wrclk, //写时钟 65M,
- rdclk, //读时钟 10M,
- rst_n, //低电平复位,同步复位,
- vsync, //场同步信号,高电平有效,
- hsync, //行同步信号,高电平有效,
- cmos_de, //使能信号,高电平有效,
- data_in, //输入数据,解码后24位RGB数据,
- depram_en,//输出使能,输出数据时置高,
- data_out, //输出数据,缓存后的24位RGB数据,
- y_cnt, //行计数器,M = 126
- wraddr, //用于测试观察,
- rdaddr //用于测试观察,
- );
- //input
- input wrclk;
- input rdclk;
- input rst_n;
- input vsync;
- input hsync;
- input cmos_de;
- input [23:0] data_in;
- //output
- output depram_en;
- output [23:0] data_out;
- output [6:0] y_cnt;
- output [7:0] wraddr;
- output [7:0] rdaddr;
- wire depram_en ;
- wire [23:0] data_out ;
- wire [6:0] y_cnt;
- wire en_wr;
- wire en_rd;
- wire [7:0] wraddr;
- wire [7:0] rdaddr;
- ram_double ip_ram1 (
- .clka(wrclk), // input clka
- //.ena(cmos_de), // input ena //选择了写使能,就把端口使能设置为一直有效,不知是否可以?
- .wea(en_wr), // input [0 : 0] wea
- .addra(wraddr), // input [7 : 0] addra
- .dina(data_in), // input [23 : 0] dina
- .clkb(rdclk), // input clkb
- //.enb(en_rd), // input enb //不知读使能如何在IP核中设置,把端口B一直设置为有效,
- .addrb(rdaddr), // input [7 : 0] addrb
- .doutb(data_out) // output [23 : 0] doutb
- );
- ram_wd ram_wd1 ( //该模块用于产生读写地址,和读写使能。
- .wrclk(wrclk),
- .rdclk(rdclk),
- .rst_n(rst_n),
- .vsync(vsync),
- .hsync(hsync),
- .cmos_de(cmos_de),
- .en_wr(en_wr),
- .en_rd(en_rd),
- .wraddr(wraddr),
- .rdaddr(rdaddr),
- .y_cnt(y_cnt)
- );
- assign depram_en = en_rd;
- endmodule
复制代码
读写地址产生及使能信号产生模块
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 09:17:24 07/31/2016
// Design Name: wuzhicheng
// Module Name: datacut
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies: 截取128X160像素点视频;
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module ram_wd(
wrclk, //写时钟 65M,
rdclk, //读时钟 10M,
rst_n, //低电平有效,
vsync, //场同步信号,高电平有效,
hsync, //行同步信号,高电平有效,
cmos_de, //使能信号,高电平有效,
en_wr,
en_rd,
wraddr,
rdaddr,
y_cnt
);
//input
input wrclk;
input rdclk;
input rst_n;
input vsync;
input hsync;
input cmos_de;
//output
output [7:0] wraddr;
output [7:0] rdaddr;
output en_wr;
output en_rd;
output [6:0] y_cnt;
wire [7:0] wraddr;
wire [7:0] rdaddr;
reg en_wr = 0;
reg en_rd = 0;
reg [6:0] y_cnt = 0; //行计数器,M=128
//---------写状态-------------
reg [4:0] cstate,nstate;
parameter
IDLE = 5'b00000, //复位;
NEW_FRAME = 5'b00001, //有效数据开始进入;
DATA = 5'b00010, //按行开始写人数据;
WAIT_NEWHC = 5'b00100, //读到某行的160列,通过cmos_de判定,0-后面数据不要了;
WAIT_NEWH = 5'b01000, //等待下一行数据;判定M=128,后面数据舍弃;
WAIT_VC = 5'b10000; //等待下一个场信号,等待下一帧数据;
//-------产生行同步信号上升沿--------
reg [1:0] hsync_reg;
wire hsync_up;
always @ (posedge wrclk)
if(!rst_n)
hsync_reg <= 0;
else
hsync_reg <={hsync_reg[0],hsync};
assign hsync_up = (hsync_reg[1]&&(~hsync_reg[0]));
//------写状态第1段-------
always @ (posedge wrclk)
if(!rst_n)
cstate <= IDLE;
else
cstate <= nstate;
//------写状态第2段------
always @ (*) begin
case (cstate)
IDLE: begin
if(vsync) nstate = NEW_FRAME;
else nstate = IDLE;
end
NEW_FRAME: begin
if(cmos_de) nstate = DATA;
else nstate = NEW_FRAME;
end
DATA: begin
if(wraddr_cnt == 160)
nstate = WAIT_NEWHC;
else
nstate = DATA;
end
WAIT_NEWHC: begin
if(!cmos_de)
nstate = WAIT_NEWH;
else
nstate = WAIT_NEWHC;
end
WAIT_NEWH: begin
if(y_cnt == 128)
nstate = WAIT_VC;
else if(cmos_de == 1)
nstate = DATA;
else
nstate = WAIT_NEWH;
end
WAIT_VC: begin
if(!vsync)
nstate = NEW_FRAME;
else
nstate = WAIT_VC;
end
default :nstate = IDLE;
endcase
end
//------写状态第三段------
reg [7:0] wraddr_cnt = 0;//写地址计数器,max=160
always @ (posedge wrclk) begin
if(!rst_n) begin
wraddr_cnt <= 0;
y_cnt <= 0;
end
else case(cstate)
DATA: begin
if(wraddr_cnt >= 160) begin
en_wr <= 0;
end
else if (hsync) begin
wraddr_cnt <= wraddr_cnt + 1'b1;
en_wr <= 1;
end
end
WAIT_NEWH: begin
wraddr_cnt <= 0;
if(y_cnt == 128)
y_cnt <= 0;
else if(hsync_up)
y_cnt <= y_cnt + 1'b1;
end
endcase
end
//-------读数据部分---------
reg [7:0] rdaddr_cnt = 0; //读地址计数器,max=160
always @(posedge rdclk) begin
if(!cmos_de) begin
rdaddr_cnt <=0;
en_rd <= 0;
end
else
if(vsync == 1) begin
if(rdaddr_cnt >= 160) begin
en_rd <= 0;
end
else
if(wraddr_cnt >= 3) begin
rdaddr_cnt <= rdaddr_cnt + 1'b1;
en_rd <= 1;
end
end
end
assign wraddr = wraddr_cnt;
assign rdaddr = rdaddr_cnt;
endmodule
测试文件:
`timescale 1ns / 1ps
////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 14:48:03 08/16/2016
// Design Name: data_cut
// Module Name: F:/FPGA/projet/test/cmos_cut/data_cut_tb.v
// Project Name: cmos_cut
// Target Device:
// Tool versions:
// Description:
//
// Verilog Test Fixture created by ISE for module: data_cut
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
////////////////////////////////////////////////////////////////////////////////
module data_cut_tb;
// Inputs
reg wrclk;
reg rdclk;
reg rst_n;
reg vsync;
reg hsync;
reg cmos_de;
reg [23:0] data_in;
// Outputs
wire depram_en;
wire [23:0] data_out;
wire [6:0] y_cnt;
wire [7:0] wraddr;
wire [7:0] rdaddr;
localparam T = 15;//写时钟为65Mhz,读时钟为10Mhz,暂近似处理;
data_cut uut (
.wrclk(wrclk),
.rdclk(rdclk),
.rst_n(rst_n),
.vsync(vsync),
.hsync(hsync),
.cmos_de(cmos_de),
.data_in(data_in),
.depram_en(depram_en),
.data_out(data_out),
.y_cnt(y_cnt),
.wraddr(wraddr),
.rdaddr(rdaddr)
);
always begin
wrclk = 0;
#(T/2);
wrclk = 1;
#(T/2);
end
always begin
rdclk = 0;
#(13/4*T);
rdclk = 1;
#(13/4*T);
end
initial begin
rst_n = 0;
#(T);
rst_n = 1;
end
always begin
cmos_de = 0;
#(320*T);
cmos_de = 1;
#(1024*T);
end
initial begin //在场信号有效的情况下处理;暂只考虑一场数据;
vsync = 0;
#(1*T);
vsync = 1;
end
always begin //一行像素点为1024,考虑到行消隐时间,所以把行周期定为1024x1.05=1344
hsync = 0;
#(320*T);
hsync = 1;
#(1024*T);
end
always @(posedge wrclk) begin
if(!rst_n)begin
data_in <=8'd0;
end
else begin
if( data_in < 8'd255 )
data_in <= data_in + 1'b1;
else
data_in <= 0;
end
end
endmodule |
|