📄 dma.v
字号:
assign status_register_write = dma_ctl_chipselect & ~dma_ctl_write_n & (dma_ctl_address == 0);
// read address
always @(posedge clk or negedge reset_n)
begin
if (reset_n == 0)
readaddress <= 26'h0;
else if (clk_en)
readaddress <= p1_readaddress;
end
assign p1_readaddress = ((dma_ctl_chipselect & ~dma_ctl_write_n & (dma_ctl_address == 1)))? dma_ctl_writedata :
(inc_read)? (readaddress + readaddress_inc) :
readaddress;
// write address
always @(posedge clk or negedge reset_n)
begin
if (reset_n == 0)
writeaddress <= 26'h0;
else if (clk_en)
writeaddress <= p1_writeaddress;
end
assign p1_writeaddress = ((dma_ctl_chipselect & ~dma_ctl_write_n & (dma_ctl_address == 2)))? dma_ctl_writedata :
(inc_write)? (writeaddress + writeaddress_inc) :
writeaddress;
// length in bytes
always @(posedge clk or negedge reset_n)
begin
if (reset_n == 0)
length <= 25'h0;
else if (clk_en)
length <= p1_length;
end
assign p1_length = ((dma_ctl_chipselect & ~dma_ctl_write_n & (dma_ctl_address == 3)))? dma_ctl_writedata :
((inc_read && (!length_eq_0)))? length - {1'b0,
1'b0,
word,
hw,
byte} :
length;
// control register
always @(posedge clk or negedge reset_n)
begin
if (reset_n == 0)
control <= 12'h84;
else if (clk_en)
control <= p1_control;
end
assign p1_control = ((dma_ctl_chipselect & ~dma_ctl_write_n & ((dma_ctl_address == 6) || (dma_ctl_address == 7))))? dma_ctl_writedata :
control;
// write master length
always @(posedge clk or negedge reset_n)
begin
if (reset_n == 0)
writelength <= 25'h0;
else if (clk_en)
writelength <= p1_writelength;
end
assign p1_writelength = ((dma_ctl_chipselect & ~dma_ctl_write_n & (dma_ctl_address == 3)))? dma_ctl_writedata :
((inc_write && (!writelength_eq_0)))? writelength - {1'b0,
1'b0,
word,
hw,
byte} :
writelength;
assign p1_writelength_eq_0 = inc_write && (!writelength_eq_0) && ((writelength - {1'b0,
1'b0,
word,
hw,
byte}) == 0);
assign p1_length_eq_0 = inc_read && (!length_eq_0) && ((length - {1'b0,
1'b0,
word,
hw,
byte}) == 0);
always @(posedge clk or negedge reset_n)
begin
if (reset_n == 0)
length_eq_0 <= 1;
else if (clk_en)
length_eq_0 <= dma_ctl_chipselect & ~dma_ctl_write_n & (dma_ctl_address == 3) ? ~|dma_ctl_writedata : p1_length_eq_0 ? 1 : length_eq_0;
end
always @(posedge clk or negedge reset_n)
begin
if (reset_n == 0)
writelength_eq_0 <= 1;
else if (clk_en)
writelength_eq_0 <= dma_ctl_chipselect & ~dma_ctl_write_n & (dma_ctl_address == 3) ? ~|dma_ctl_writedata : p1_writelength_eq_0 ? 1 : writelength_eq_0;
end
assign writeaddress_inc = (wcon)? 0 :
{1'b0,
1'b0,
word,
hw,
byte};
assign readaddress_inc = (rcon)? 0 :
{1'b0,
1'b0,
word,
hw,
byte};
assign p1_dma_ctl_readdata = ({26 {(dma_ctl_address == 0)}} & status) |
({26 {(dma_ctl_address == 1)}} & readaddress) |
({26 {(dma_ctl_address == 2)}} & writeaddress) |
({26 {(dma_ctl_address == 3)}} & writelength) |
({26 {(dma_ctl_address == 6)}} & control);
always @(posedge clk or negedge reset_n)
begin
if (reset_n == 0)
dma_ctl_readdata <= 0;
else if (clk_en)
dma_ctl_readdata <= p1_dma_ctl_readdata;
end
assign done_transaction = go & done_write;
always @(posedge clk or negedge reset_n)
begin
if (reset_n == 0)
done <= 0;
else if (clk_en)
if (status_register_write)
done <= 0;
else if (done_transaction & ~d1_done_transaction)
done <= -1;
end
always @(posedge clk or negedge reset_n)
begin
if (reset_n == 0)
d1_done_transaction <= 0;
else if (clk_en)
d1_done_transaction <= done_transaction;
end
assign busy = go & ~done_write;
assign status[0] = done;
assign status[1] = busy;
assign status[2] = reop;
assign status[3] = weop;
assign status[4] = len;
assign byte = control[0];
assign hw = control[1];
assign word = control[2];
assign go = control[3];
assign i_en = control[4];
assign reen = control[5];
assign ween = control[6];
assign leen = control[7];
assign rcon = control[8];
assign wcon = control[9];
assign doubleword = control[10];
assign quadword = control[11];
assign dma_ctl_irq = i_en & done;
assign p1_read_got_endofpacket = ~status_register_write && (read_got_endofpacket || (read_endofpacket & reen));
assign p1_write_got_endofpacket = ~status_register_write && (write_got_endofpacket || (inc_write & write_endofpacket & ween));
always @(posedge clk or negedge reset_n)
begin
if (reset_n == 0)
read_got_endofpacket <= 0;
else if (clk_en)
read_got_endofpacket <= p1_read_got_endofpacket;
end
always @(posedge clk or negedge reset_n)
begin
if (reset_n == 0)
write_got_endofpacket <= 0;
else if (clk_en)
write_got_endofpacket <= p1_write_got_endofpacket;
end
assign flush_fifo = ~d1_done_transaction & done_transaction;
dma_fifo_module the_dma_fifo_module
(
.clk (clk),
.clk_en (clk_en),
.fifo_datavalid (fifo_datavalid),
.fifo_empty (fifo_empty),
.fifo_rd_data (fifo_rd_data),
.fifo_read (fifo_read),
.fifo_wr_data (fifo_wr_data),
.fifo_write (fifo_write),
.flush_fifo (flush_fifo),
.inc_pending_data (inc_read),
.p1_fifo_full (p1_fifo_full),
.reset_n (reset_n)
);
dma_mem_read the_dma_mem_read
(
.clk (clk),
.clk_en (clk_en),
.go (go),
.inc_read (inc_read),
.mem_read_n (mem_read_n),
.p1_done_read (p1_done_read),
.p1_fifo_full (p1_fifo_full),
.read_select (read_select),
.read_waitrequest (read_waitrequest),
.reset_n (reset_n)
);
assign fifo_write = fifo_write_data_valid;
assign enabled_write_endofpacket = write_endofpacket & ween;
always @(posedge clk or negedge reset_n)
begin
if (reset_n == 0)
d1_enabled_write_endofpacket <= 0;
else if (clk_en)
d1_enabled_write_endofpacket <= enabled_write_endofpacket;
end
dma_mem_write the_dma_mem_write
(
.d1_enabled_write_endofpacket (d1_enabled_write_endofpacket),
.fifo_datavalid (fifo_datavalid),
.fifo_read (fifo_read),
.inc_write (inc_write),
.mem_write_n (mem_write_n),
.write_select (write_select),
.write_waitrequest (write_waitrequest)
);
assign p1_done_read = (leen && (p1_length_eq_0 || (length_eq_0))) | p1_read_got_endofpacket | p1_done_write;
always @(posedge clk or negedge reset_n)
begin
if (reset_n == 0)
len <= 0;
else if (clk_en)
if (status_register_write)
len <= 0;
else if (~d1_done_transaction & done_transaction && (writelength_eq_0))
len <= -1;
end
always @(posedge clk or negedge reset_n)
begin
if (reset_n == 0)
reop <= 0;
else if (clk_en)
if (status_register_write)
reop <= 0;
else if (fifo_empty & read_got_endofpacket & d1_read_got_endofpacket)
reop <= -1;
end
always @(posedge clk or negedge reset_n)
begin
if (reset_n == 0)
weop <= 0;
else if (clk_en)
if (status_register_write)
weop <= 0;
else if (write_got_endofpacket)
weop <= -1;
end
assign p1_done_write = (leen && (p1_writelength_eq_0 || writelength_eq_0)) | p1_write_got_endofpacket | fifo_empty & d1_read_got_endofpacket;
always @(posedge clk or negedge reset_n)
begin
if (reset_n == 0)
d1_read_got_endofpacket <= 0;
else if (clk_en)
d1_read_got_endofpacket <= read_got_endofpacket;
end
// Write has completed when the length goes to 0, or
//the write source said end-of-packet, or
//the read source said end-of-packet and the fifo has emptied.
always @(posedge clk or negedge reset_n)
begin
if (reset_n == 0)
done_write <= 0;
else if (clk_en)
done_write <= p1_done_write;
end
assign read_address = readaddress;
assign write_address = writeaddress;
assign write_chipselect = write_select;
assign read_chipselect = read_select;
assign read_read_n = mem_read_n;
assign write_write_n = mem_write_n;
assign read_flush = flush_fifo;
assign fifo_rd_data_as_byte = {fifo_rd_data[7 : 0],
fifo_rd_data[7 : 0],
fifo_rd_data[7 : 0],
fifo_rd_data[7 : 0]};
assign fifo_rd_data_as_hw = {fifo_rd_data[15 : 0],
fifo_rd_data[15 : 0]};
assign fifo_rd_data_as_word = fifo_rd_data[31 : 0];
assign write_writedata = ({32 {byte}} & fifo_rd_data_as_byte) |
({32 {hw}} & fifo_rd_data_as_hw) |
({32 {word}} & fifo_rd_data_as_word);
assign fifo_write_data_valid = read_readdatavalid;
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -