📄 dma.v
字号:
//Copyright (C) 1991-2004 Altera Corporation
//Any megafunction design, and related net list (encrypted or decrypted),
//support information, device programming or simulation file, and any other
//associated documentation or information provided by Altera or a partner
//under Altera's Megafunction Partnership Program may be used only to
//program PLD devices (but not masked PLD devices) from Altera. Any other
//use of such megafunction design, net list, support information, device
//programming or simulation file, or any other related documentation or
//information is prohibited for any other purpose, including, but not
//limited to modification, reverse engineering, de-compiling, or use with
//any other silicon devices, unless such use is explicitly licensed under
//a separate agreement with Altera or a megafunction partner. Title to
//the intellectual property, including patents, copyrights, trademarks,
//trade secrets, or maskworks, embodied in any such megafunction design,
//net list, support information, device programming or simulation file, or
//any other related documentation or information provided by Altera or a
//megafunction partner, remains with Altera, the megafunction partner, or
//their respective licensors. No other licenses, including any licenses
//needed under any third party's intellectual property, are provided herein.
//Copying or modifying any file, or portion thereof, to which this notice
//is attached violates this copyright.
// synthesis translate_off
`timescale 1ns / 100ps
// synthesis translate_on
module dma_read_data_mux (
// inputs:
byte,
clk,
clk_en,
dma_ctl_address,
dma_ctl_chipselect,
dma_ctl_write_n,
dma_ctl_writedata,
hw,
read_readdata,
read_readdatavalid,
readaddress,
readaddress_inc,
reset_n,
word,
// outputs:
fifo_wr_data
);
output [ 31: 0] fifo_wr_data;
input byte;
input clk;
input clk_en;
input [ 2: 0] dma_ctl_address;
input dma_ctl_chipselect;
input dma_ctl_write_n;
input [ 25: 0] dma_ctl_writedata;
input hw;
input [ 31: 0] read_readdata;
input read_readdatavalid;
input [ 25: 0] readaddress;
input [ 4: 0] readaddress_inc;
input reset_n;
input word;
wire control_write;
wire [ 31: 0] fifo_wr_data;
wire [ 1: 0] read_data_mux_input;
reg [ 1: 0] readdata_mux_select;
assign control_write = dma_ctl_chipselect & ~dma_ctl_write_n & ((dma_ctl_address == 6) || (dma_ctl_address == 7));
assign read_data_mux_input = ((control_write && (dma_ctl_writedata[3])))? readaddress[1 : 0] :
(read_readdatavalid)? (readdata_mux_select + readaddress_inc) :
readdata_mux_select;
// Reset value: the transaction size bits of the read address reset value.
always @(posedge clk or negedge reset_n)
begin
if (reset_n == 0)
readdata_mux_select <= 0;
else if (clk_en)
readdata_mux_select <= read_data_mux_input[1 : 0];
end
assign fifo_wr_data[31 : 16] = read_readdata[31 : 16];
assign fifo_wr_data[15 : 8] = ({8 {(hw & (readdata_mux_select[1] == 0))}} & read_readdata[15 : 8]) |
({8 {(hw & (readdata_mux_select[1] == 1))}} & read_readdata[31 : 24]) |
({8 {word}} & read_readdata[15 : 8]);
assign fifo_wr_data[7 : 0] = ({8 {(byte & (readdata_mux_select[1 : 0] == 0))}} & read_readdata[7 : 0]) |
({8 {(byte & (readdata_mux_select[1 : 0] == 1))}} & read_readdata[15 : 8]) |
({8 {(byte & (readdata_mux_select[1 : 0] == 2))}} & read_readdata[23 : 16]) |
({8 {(byte & (readdata_mux_select[1 : 0] == 3))}} & read_readdata[31 : 24]) |
({8 {(hw & (readdata_mux_select[1] == 0))}} & read_readdata[7 : 0]) |
({8 {(hw & (readdata_mux_select[1] == 1))}} & read_readdata[23 : 16]) |
({8 {word}} & read_readdata[7 : 0]);
endmodule
module dma_byteenables (
// inputs:
byte,
hw,
word,
write_address,
// outputs:
write_byteenable
);
output [ 3: 0] write_byteenable;
input byte;
input hw;
input word;
input [ 25: 0] write_address;
wire wa_1_is_0;
wire wa_1_is_1;
wire wa_1_to_0_is_0;
wire wa_1_to_0_is_1;
wire wa_1_to_0_is_2;
wire wa_1_to_0_is_3;
wire [ 3: 0] write_byteenable;
assign wa_1_to_0_is_3 = write_address[1 : 0] == 2'h3;
assign wa_1_to_0_is_2 = write_address[1 : 0] == 2'h2;
assign wa_1_to_0_is_1 = write_address[1 : 0] == 2'h1;
assign wa_1_to_0_is_0 = write_address[1 : 0] == 2'h0;
assign wa_1_is_1 = write_address[1] == 1'h1;
assign wa_1_is_0 = write_address[1] == 1'h0;
assign write_byteenable = ({4 {byte}} & {wa_1_to_0_is_3, wa_1_to_0_is_2, wa_1_to_0_is_1, wa_1_to_0_is_0}) |
({4 {hw}} & {wa_1_is_1, wa_1_is_1, wa_1_is_0, wa_1_is_0}) |
({4 {word}} & 4'b1111);
endmodule
module dma_fifo_module_fifo_ram_module (
// inputs:
clk,
data,
rdaddress,
rdclken,
reset_n,
wraddress,
wrclock,
wren,
// outputs:
q
);
output [ 31: 0] q;
input clk;
input [ 31: 0] data;
input [ 2: 0] rdaddress;
input rdclken;
input reset_n;
input [ 2: 0] wraddress;
input wrclock;
input wren;
reg [ 31: 0] mem_array [ 7: 0];
wire [ 31: 0] q;
reg [ 2: 0] read_address;
//synthesis translate_off
//////////////// SIMULATION-ONLY CONTENTS
always @(posedge clk or negedge reset_n)
begin
if (reset_n == 0)
read_address <= 0;
else if (rdclken)
read_address <= rdaddress;
end
// Data read is synchronized through latent_rdaddress.
assign q = mem_array[read_address];
always @(posedge wrclock)
begin
// Write data
if (wren)
mem_array[wraddress] <= data;
end
//////////////// END SIMULATION-ONLY CONTENTS
//synthesis translate_on
//synthesis read_comments_as_HDL on
// always @(rdaddress)
// begin
// if (1)
// read_address <= rdaddress;
// end
//
//
// lpm_ram_dp lpm_ram_dp_component
// (
// .data (data),
// .q (q),
// .rdaddress (read_address),
// .rdclken (rdclken),
// .rdclock (clk),
// .wraddress (wraddress),
// .wrclock (wrclock),
// .wren (wren)
// );
//
// defparam lpm_ram_dp_component.lpm_file = "UNUSED",
// lpm_ram_dp_component.lpm_hint = "USE_EAB=OFF",
// lpm_ram_dp_component.lpm_indata = "REGISTERED",
// lpm_ram_dp_component.lpm_outdata = "UNREGISTERED",
// lpm_ram_dp_component.lpm_rdaddress_control = "REGISTERED",
// lpm_ram_dp_component.lpm_width = 32,
// lpm_ram_dp_component.lpm_widthad = 3,
// lpm_ram_dp_component.lpm_wraddress_control = "REGISTERED",
// lpm_ram_dp_component.suppress_memory_conversion_warnings = "ON";
//
//synthesis read_comments_as_HDL off
endmodule
module dma_fifo_module (
// inputs:
clk,
clk_en,
fifo_read,
fifo_wr_data,
fifo_write,
flush_fifo,
inc_pending_data,
reset_n,
// outputs:
fifo_datavalid,
fifo_empty,
fifo_rd_data,
p1_fifo_full
);
output fifo_datavalid;
output fifo_empty;
output [ 31: 0] fifo_rd_data;
output p1_fifo_full;
input clk;
input clk_en;
input fifo_read;
input [ 31: 0] fifo_wr_data;
input fifo_write;
input flush_fifo;
input inc_pending_data;
input reset_n;
wire [ 2: 0] estimated_rdaddress;
reg [ 2: 0] estimated_wraddress;
wire fifo_datavalid;
wire fifo_dec;
reg fifo_empty;
reg fifo_full;
wire fifo_inc;
wire [ 31: 0] fifo_ram_q;
wire [ 31: 0] fifo_rd_data;
reg last_write_collision;
reg [ 31: 0] last_write_data;
wire [ 2: 0] p1_estimated_wraddress;
wire p1_fifo_empty;
wire p1_fifo_full;
wire [ 2: 0] p1_wraddress;
wire [ 2: 0] rdaddress;
reg [ 2: 0] rdaddress_reg;
reg [ 2: 0] wraddress;
wire write_collision;
assign p1_wraddress = (fifo_write)? wraddress - 1 :
wraddress;
always @(posedge clk or negedge reset_n)
begin
if (reset_n == 0)
wraddress <= 0;
else if (clk_en)
if (flush_fifo)
wraddress <= 0;
else
wraddress <= p1_wraddress;
end
assign rdaddress = flush_fifo ? 0 : fifo_read ? (rdaddress_reg - 1) : rdaddress_reg;
always @(posedge clk or negedge reset_n)
begin
if (reset_n == 0)
rdaddress_reg <= 0;
else if (1)
rdaddress_reg <= rdaddress;
end
assign fifo_datavalid = ~fifo_empty;
assign fifo_inc = fifo_write & ~fifo_read;
assign fifo_dec = fifo_read & ~fifo_write;
assign estimated_rdaddress = rdaddress_reg - 1;
assign p1_estimated_wraddress = (inc_pending_data)? estimated_wraddress - 1 :
estimated_wraddress;
always @(posedge clk or negedge reset_n)
begin
if (reset_n == 0)
estimated_wraddress <= {3 {1'b1}};
else if (clk_en)
if (flush_fifo)
estimated_wraddress <= {3 {1'b1}};
else
estimated_wraddress <= p1_estimated_wraddress;
end
assign p1_fifo_empty = flush_fifo | ((~fifo_inc & fifo_empty) | (fifo_dec & (wraddress == estimated_rdaddress)));
always @(posedge clk or negedge reset_n)
begin
if (reset_n == 0)
fifo_empty <= 1;
else if (clk_en)
fifo_empty <= p1_fifo_empty;
end
assign p1_fifo_full = ~flush_fifo & ((~fifo_dec & fifo_full) | (inc_pending_data & (estimated_wraddress == rdaddress)));
always @(posedge clk or negedge reset_n)
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -