|
我的程序为什么在读buffer里面的数据到屏幕的时候(buffer里面的数据是从1到500循环),会将里面的数据多读出来100个,也就是说,先读出1到500的数据,显示到屏幕上,接着又多余读出100个,什么原因呢?请各位高手帮我看看程序。最主要的是最下面的状态机这个过程,看有啥错误,望指出。
`timescale 1ps/1ps
module master_write_burst_last
(
clk,
reset_n,
//
dclk,
data,(1到500循环)
de,
hs,
vs,
//
write_address_base1,
write_address_base2,
write_length_base,
write_burstcount_base,
wirte_en,
write_done,
write_indicator,
// dma read
avm_address,
avm_write,
avm_byteenable,
avm_writedata,
avm_burstcount,
avm_waitrequest
);
parameter DATAWIDTH = 32;
parameter MAXBURSTCOUNT = 64;
parameter BYTEENABLEWIDTH = 4;
parameter ADDRESSWIDTH = 32;
parameter ADDR_SHIF = 2; //log2(BYTEENABLEWIDTH)
parameter BURSTCOUNTWIDTH = 16;
// av signal
input clk;
input reset_n;
input avm_waitrequest;
output wire [DATAWIDTH-1:0] avm_writedata;
output wire [ADDRESSWIDTH-1:0] avm_address;
output reg avm_write;
output wire [BYTEENABLEWIDTH-1:0] avm_byteenable;
output wire [BURSTCOUNTWIDTH-1:0] avm_burstcount;
input dclk;
input [11:0] data;
input de;
input hs;
input vs;
input [ADDRESSWIDTH-1:0] write_address_base1;
input [ADDRESSWIDTH-1:0] write_address_base2;
input [ADDRESSWIDTH-1:0] write_length_base;
input [ADDRESSWIDTH-1:0] write_burstcount_base;
input wirte_en;
output write_done;
output reg write_indicator;
reg write_done;
reg control_done;
reg [BURSTCOUNTWIDTH-1:0] write_cnt;
reg [ADDRESSWIDTH-1:0] wr_address;
reg [ADDRESSWIDTH-1:0] wr_length;
reg [BURSTCOUNTWIDTH-1:0] wr_burst_count;
reg [3:0] wr_status;
reg vsreg,vsreg_rr;
reg hs_q;
reg vs_q;
reg hs_q_q;
always @(posedge clk ,negedge reset_n)
begin
if(!reset_n)
begin
vsreg <= 0;
vsreg_rr <= 0;
end
else
begin
vsreg <= vs;
vsreg_rr <= vsreg;
end
end
reg video_reset_n;
reg [4:0] video_reset_cnt;
always @(posedge clk or negedge reset_n)
begin
if(~reset_n)
begin
video_reset_n <=0;
video_reset_cnt <=0;
end
else if((vsreg ==1) && (vsreg_rr==0))
begin
video_reset_cnt <=0;
video_reset_n <=0;
end
else
begin
if(video_reset_cnt >10)
begin
video_reset_n <= 1;
video_reset_cnt <= video_reset_cnt;
end
else
begin
video_reset_cnt <= video_reset_cnt +1;
end
end
end
wire fifo_reset = (~video_reset_n); //
wire fifo_wrclk = dclk;
wire fifo_wrreq =(de & wirte_en );
wire [15:0] fifo_data_in;
assign fifo_data_in ={4'b0000,data};
wire fifo_full;
wire fifo_rdclk = clk;
wire fifo_rdreq = (avm_write && (avm_waitrequest == 0));
wire [DATAWIDTH-1:0] fifo_data_out;
wire [9:0] fifo_used;
wire fifo_rdempty;
//assign fifo_data_in ={16'h0000,rgb_tmp};
wr_fifo wr_fifo_inst
(
.aclr(fifo_reset),
.wrclk(fifo_wrclk),
.wrreq(fifo_wrreq),
.data(fifo_data_in),
.wrfull(fifo_full),
.rdclk(clk),
.rdreq(fifo_rdreq),
.q(fifo_data_out),
.rdusedw(fifo_used),
.rdempty(fifo_rdempty)
);
//////////////////////////////////////////
reg wirte_en_r;
reg wirte_en_rr;
reg write_m_en;
reg image_en;
always @(posedge clk ,negedge reset_n)
begin
if(!reset_n)
begin
wirte_en_r <= 0;
wirte_en_rr <= 0;
end
else
begin
wirte_en_r <= wirte_en;
wirte_en_rr <= wirte_en_r;
end
end
always @(posedge clk ,negedge reset_n)
begin
if(!reset_n)
begin
write_m_en <=0;
end
else
begin
if((wirte_en_rr == 0)&&(wirte_en_r == 1))
begin
write_m_en <= 1;
end
else if(wirte_en ==0)
begin
write_m_en <= 0;
end
else
begin
write_m_en <= write_m_en;
end
end
end
////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
reg wr_start;
always @(posedge clk or negedge reset_n)
begin
if(reset_n == 0)
begin
wr_start<= 0;
end
else if(video_reset_n==0)
begin
if(write_m_en && image_en==1 && vs_q ==1)
begin
wr_start <= 1;
end
else
begin
wr_start <= 0;
end
end
else
begin
wr_start <= wr_start;
end
end
always @(posedge clk or negedge reset_n)
begin
if(reset_n==0)
begin
image_en <=0;
end
else
begin
if((hs_q_q == 0) && (hs_q == 1))
begin
image_en <= 1;
end
else if(hs_q == 0)
begin
image_en <= 0;
end
else
begin
image_en <= image_en;
end
end
end
//////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
parameter WR_IDLE = 0;
parameter WR_WRITE = 1;
parameter WR_WAIT = 2;
parameter WR_OVER = 3;
parameter WR_END = 4;
reg indicator;
always @ (posedge clk or negedge reset_n)
begin
if (reset_n == 0)
begin
hs_q<= 0;
hs_q_q<= 0;
vs_q<= 0;
end
else
begin
hs_q<= hs;
vs_q<= vs;
hs_q_q<= hs_q;
end
end
always @ (posedge clk or negedge reset_n)
begin
if (reset_n == 0)
begin
avm_write <=0;
write_cnt <= 0;
write_done <= 0;
write_indicator<= 0;
wr_status <=WR_IDLE;
wr_address <=write_address_base1;
wr_burst_count <=write_burstcount_base[BURSTCOUNTWIDTH-1:0];
wr_length <=write_length_base;
end
else
if(wr_start)
begin
case (wr_status)
WR_IDLE:
begin
write_cnt <= 0;
write_done <=0;
avm_write <= 0;
if (~write_indicator)
wr_address <= write_address_base1;
else
wr_address <= write_address_base2;
wr_length <= write_length_base;
if(fifo_used >=(write_burstcount_base[BURSTCOUNTWIDTH-1:0]))
begin
wr_burst_count <= write_burstcount_base[7:0];
avm_write <= 1;
wr_status <= WR_WRITE;
end
end
WR_WRITE:
begin
if(avm_waitrequest == 0)
begin
if(write_cnt == (wr_burst_count-1))
begin
wr_length <= wr_length - (wr_burst_count<<ADDR_SHIF);
wr_address <= wr_address + (wr_burst_count<<ADDR_SHIF);
avm_write <= 0;
wr_status <= WR_WAIT;
end
else
begin
write_cnt <= write_cnt + 1;
end
end
end
WR_WAIT:
begin
if((wr_length == 0))
begin
wr_status <= WR_OVER;
write_done <= 1;
write_cnt <= 0;
end
else
begin
if(fifo_used >=wr_burst_count)
begin
avm_write <= 1;
write_cnt <= 0;
wr_status <= WR_WRITE;
if(wr_length < (wr_burst_count<<ADDR_SHIF))
begin
wr_burst_count <= (wr_burst_count<<ADDR_SHIF)-wr_length[BURSTCOUNTWIDTH-1:0];
end
end
end
end
WR_OVER:
begin
if(~write_indicator)
begin
wr_status <= WR_IDLE;
write_indicator <= ~write_indicator;
end
else
begin
wr_status <= WR_END;
end
end
WR_END:
begin
wr_status <= WR_END;
end
endcase
end
else
begin
avm_write <= 0;
write_cnt <= 0;
wr_status <= WR_IDLE;
write_done <= 0;
end
end
/////////////////////////////////////////////////////////////////////
assign avm_byteenable = -1;
assign avm_address = wr_address;
assign avm_burstcount = wr_burst_count;
assign avm_writedata = fifo_data_out;
endmodule |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|