mirror of
https://github.com/pConst/basic_verilog.git
synced 2025-01-14 06:42:54 +08:00
Added Avalon master templates
This commit is contained in:
parent
5bde0a502e
commit
7399deb17d
BIN
avalon_mm_master_templates/Avalon_MM_Masters_Readme.pdf
Normal file
BIN
avalon_mm_master_templates/Avalon_MM_Masters_Readme.pdf
Normal file
Binary file not shown.
256
avalon_mm_master_templates/burst_read_master.v
Normal file
256
avalon_mm_master_templates/burst_read_master.v
Normal file
@ -0,0 +1,256 @@
|
||||
/*
|
||||
Legal Notice: (C)2007 Altera Corporation. All rights reserved. Your
|
||||
use of Altera Corporation's design tools, logic functions and other
|
||||
software and tools, and its AMPP partner logic functions, and any
|
||||
output files any of the foregoing (including device programming or
|
||||
simulation files), and any associated documentation or information are
|
||||
expressly subject to the terms and conditions of the Altera Program
|
||||
License Subscription Agreement or other applicable license agreement,
|
||||
including, without limitation, that your use is for the sole purpose
|
||||
of programming logic devices manufactured by Altera and sold by Altera
|
||||
or its authorized distributors. Please refer to the applicable
|
||||
agreement for further details.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Author: JCJB
|
||||
Date: 11/04/2007
|
||||
|
||||
This bursting read master is passed a word aligned address, length in bytes,
|
||||
and a 'go' bit. The master will continue to post full length bursts until
|
||||
the length register reaches a value less than a full burst. A single final
|
||||
burst is then posted and when all the reads return the done bit will be asserted.
|
||||
|
||||
To use this master you must simply drive the control signals into this block,
|
||||
and also read the data from the exposed read FIFO. To read from the exposed FIFO
|
||||
use the 'user_read_buffer' signal to pop data from the FIFO 'user_buffer_data'.
|
||||
The signal 'user_data_available' is asserted whenever data is available from the
|
||||
exposed FIFO.
|
||||
|
||||
*/
|
||||
|
||||
// altera message_off 10230
|
||||
|
||||
|
||||
module burst_read_master (
|
||||
clk,
|
||||
reset,
|
||||
|
||||
// control inputs and outputs
|
||||
control_fixed_location,
|
||||
control_read_base,
|
||||
control_read_length,
|
||||
control_go,
|
||||
control_done,
|
||||
control_early_done,
|
||||
|
||||
// user logic inputs and outputs
|
||||
user_read_buffer,
|
||||
user_buffer_data,
|
||||
user_data_available,
|
||||
|
||||
// master inputs and outputs
|
||||
master_address,
|
||||
master_read,
|
||||
master_byteenable,
|
||||
master_readdata,
|
||||
master_readdatavalid,
|
||||
master_burstcount,
|
||||
master_waitrequest
|
||||
);
|
||||
|
||||
parameter DATAWIDTH = 32;
|
||||
parameter MAXBURSTCOUNT = 4;
|
||||
parameter BURSTCOUNTWIDTH = 3;
|
||||
parameter BYTEENABLEWIDTH = 4;
|
||||
parameter ADDRESSWIDTH = 32;
|
||||
parameter FIFODEPTH = 32;
|
||||
parameter FIFODEPTH_LOG2 = 5;
|
||||
parameter FIFOUSEMEMORY = 1; // set to 0 to use LEs instead
|
||||
|
||||
input clk;
|
||||
input reset;
|
||||
|
||||
|
||||
// control inputs and outputs
|
||||
input control_fixed_location;
|
||||
input [ADDRESSWIDTH-1:0] control_read_base;
|
||||
input [ADDRESSWIDTH-1:0] control_read_length;
|
||||
input control_go;
|
||||
output wire control_done;
|
||||
output wire control_early_done; // don't use this unless you know what you are doing, it's going to fire when the last read is posted, not when the last data returns!
|
||||
|
||||
// user logic inputs and outputs
|
||||
input user_read_buffer;
|
||||
output wire [DATAWIDTH-1:0] user_buffer_data;
|
||||
output wire user_data_available;
|
||||
|
||||
// master inputs and outputs
|
||||
input master_waitrequest;
|
||||
input master_readdatavalid;
|
||||
input [DATAWIDTH-1:0] master_readdata;
|
||||
output wire [ADDRESSWIDTH-1:0] master_address;
|
||||
output wire master_read;
|
||||
output wire [BYTEENABLEWIDTH-1:0] master_byteenable;
|
||||
output wire [BURSTCOUNTWIDTH-1:0] master_burstcount;
|
||||
|
||||
// internal control signals
|
||||
reg control_fixed_location_d1;
|
||||
wire fifo_empty;
|
||||
reg [ADDRESSWIDTH-1:0] address;
|
||||
reg [ADDRESSWIDTH-1:0] length;
|
||||
reg [FIFODEPTH_LOG2-1:0] reads_pending;
|
||||
wire increment_address;
|
||||
wire [BURSTCOUNTWIDTH-1:0] burst_count;
|
||||
wire [BURSTCOUNTWIDTH-1:0] first_short_burst_count;
|
||||
wire first_short_burst_enable;
|
||||
wire [BURSTCOUNTWIDTH-1:0] final_short_burst_count;
|
||||
wire final_short_burst_enable;
|
||||
wire [BURSTCOUNTWIDTH-1:0] burst_boundary_word_address;
|
||||
reg burst_begin;
|
||||
wire too_many_reads_pending;
|
||||
wire [FIFODEPTH_LOG2-1:0] fifo_used;
|
||||
|
||||
|
||||
|
||||
// registering the control_fixed_location bit
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin
|
||||
if (reset == 1)
|
||||
begin
|
||||
control_fixed_location_d1 <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (control_go == 1)
|
||||
begin
|
||||
control_fixed_location_d1 <= control_fixed_location;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
// master address logic
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin
|
||||
if (reset == 1)
|
||||
begin
|
||||
address <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if(control_go == 1)
|
||||
begin
|
||||
address <= control_read_base;
|
||||
end
|
||||
else if((increment_address == 1) & (control_fixed_location_d1 == 0))
|
||||
begin
|
||||
address <= address + (burst_count * BYTEENABLEWIDTH); // always performing word size accesses, increment by the burst count presented
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
// master length logic
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin
|
||||
if (reset == 1)
|
||||
begin
|
||||
length <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if(control_go == 1)
|
||||
begin
|
||||
length <= control_read_length;
|
||||
end
|
||||
else if(increment_address == 1)
|
||||
begin
|
||||
length <= length - (burst_count * BYTEENABLEWIDTH); // always performing word size accesses, decrement by the burst count presented
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
// controlled signals going to the master/control ports
|
||||
assign master_address = address;
|
||||
assign master_byteenable = -1; // all ones, always performing word size accesses
|
||||
assign master_burstcount = burst_count;
|
||||
assign control_done = (length == 0) & (reads_pending == 0); // need to make sure that the reads have returned before firing the done bit
|
||||
assign control_early_done = (length == 0); // advanced feature, you should use 'control_done' if you need all the reads to return first
|
||||
assign master_read = (too_many_reads_pending == 0) & (length != 0);
|
||||
assign burst_boundary_word_address = ((address / BYTEENABLEWIDTH) & (MAXBURSTCOUNT - 1));
|
||||
assign first_short_burst_enable = (burst_boundary_word_address != 0);
|
||||
assign final_short_burst_enable = (length < (MAXBURSTCOUNT * BYTEENABLEWIDTH));
|
||||
|
||||
assign first_short_burst_count = ((burst_boundary_word_address & 1'b1) == 1'b1)? 1 : // if the burst boundary isn't a multiple of 2 then must post a burst of 1 to get to a multiple of 2 for the next burst
|
||||
(((MAXBURSTCOUNT - burst_boundary_word_address) < (length / BYTEENABLEWIDTH))?
|
||||
(MAXBURSTCOUNT - burst_boundary_word_address) : (length / BYTEENABLEWIDTH));
|
||||
assign final_short_burst_count = (length / BYTEENABLEWIDTH);
|
||||
|
||||
assign burst_count = (first_short_burst_enable == 1)? first_short_burst_count : // this will get the transfer back on a burst boundary,
|
||||
(final_short_burst_enable == 1)? final_short_burst_count : MAXBURSTCOUNT;
|
||||
assign increment_address = (too_many_reads_pending == 0) & (master_waitrequest == 0) & (length != 0);
|
||||
assign too_many_reads_pending = (reads_pending + fifo_used) >= (FIFODEPTH - MAXBURSTCOUNT - 4); // make sure there are fewer reads posted than room in the FIFO
|
||||
|
||||
|
||||
// tracking FIFO
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin
|
||||
if (reset == 1)
|
||||
begin
|
||||
reads_pending <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if(increment_address == 1)
|
||||
begin
|
||||
if(master_readdatavalid == 0)
|
||||
begin
|
||||
reads_pending <= reads_pending + burst_count;
|
||||
end
|
||||
else
|
||||
begin
|
||||
reads_pending <= reads_pending + burst_count - 1; // a burst read was posted, but a word returned
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
if(master_readdatavalid == 0)
|
||||
begin
|
||||
reads_pending <= reads_pending; // burst read was not posted and no read returned
|
||||
end
|
||||
else
|
||||
begin
|
||||
reads_pending <= reads_pending - 1; // burst read was not posted but a word returned
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// read data feeding user logic
|
||||
assign user_data_available = !fifo_empty;
|
||||
scfifo the_master_to_user_fifo (
|
||||
.aclr (reset),
|
||||
.clock (clk),
|
||||
.data (master_readdata),
|
||||
.empty (fifo_empty),
|
||||
.q (user_buffer_data),
|
||||
.rdreq (user_read_buffer),
|
||||
.usedw (fifo_used),
|
||||
.wrreq (master_readdatavalid)
|
||||
);
|
||||
defparam the_master_to_user_fifo.lpm_width = DATAWIDTH;
|
||||
defparam the_master_to_user_fifo.lpm_numwords = FIFODEPTH;
|
||||
defparam the_master_to_user_fifo.lpm_showahead = "ON";
|
||||
defparam the_master_to_user_fifo.use_eab = (FIFOUSEMEMORY == 1)? "ON" : "OFF";
|
||||
defparam the_master_to_user_fifo.add_ram_output_register = "OFF";
|
||||
defparam the_master_to_user_fifo.underflow_checking = "OFF";
|
||||
defparam the_master_to_user_fifo.overflow_checking = "OFF";
|
||||
|
||||
endmodule
|
305
avalon_mm_master_templates/burst_write_master.v
Normal file
305
avalon_mm_master_templates/burst_write_master.v
Normal file
@ -0,0 +1,305 @@
|
||||
/*
|
||||
Legal Notice: (C)2007 Altera Corporation. All rights reserved. Your
|
||||
use of Altera Corporation's design tools, logic functions and other
|
||||
software and tools, and its AMPP partner logic functions, and any
|
||||
output files any of the foregoing (including device programming or
|
||||
simulation files), and any associated documentation or information are
|
||||
expressly subject to the terms and conditions of the Altera Program
|
||||
License Subscription Agreement or other applicable license agreement,
|
||||
including, without limitation, that your use is for the sole purpose
|
||||
of programming logic devices manufactured by Altera and sold by Altera
|
||||
or its authorized distributors. Please refer to the applicable
|
||||
agreement for further details.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Author: JCJB
|
||||
Date: 11/04/2007
|
||||
|
||||
This bursting write master is passed a word aligned address, length in bytes,
|
||||
and a 'go' bit. The master will continue to post full length bursts until
|
||||
the length register reaches a value less than a full burst. A single final
|
||||
burst is then posted when enough data has been buffered and then the done bit
|
||||
will be asserted.
|
||||
|
||||
To use this master you must simply drive the control signals into this block,
|
||||
and also write the data to the exposed write FIFO. To read from the exposed FIFO
|
||||
use the 'user_write_buffer' signal to push data into the FIFO 'user_buffer_data'.
|
||||
The signal 'user_buffer_full' is asserted whenever the exposed buffer is full.
|
||||
You should not attempt to write data to the exposed FIFO if it is full.
|
||||
|
||||
*/
|
||||
|
||||
// altera message_off 10230
|
||||
|
||||
|
||||
module burst_write_master (
|
||||
clk,
|
||||
reset,
|
||||
|
||||
// control inputs and outputs
|
||||
control_fixed_location,
|
||||
control_write_base,
|
||||
control_write_length,
|
||||
control_go,
|
||||
control_done,
|
||||
|
||||
// user logic inputs and outputs
|
||||
user_write_buffer,
|
||||
user_buffer_data,
|
||||
user_buffer_full,
|
||||
|
||||
// master inputs and outputs
|
||||
master_address,
|
||||
master_write,
|
||||
master_byteenable,
|
||||
master_writedata,
|
||||
master_burstcount,
|
||||
master_waitrequest
|
||||
);
|
||||
|
||||
|
||||
parameter DATAWIDTH = 32;
|
||||
parameter MAXBURSTCOUNT = 4;
|
||||
parameter BURSTCOUNTWIDTH = 3;
|
||||
parameter BYTEENABLEWIDTH = 4;
|
||||
parameter ADDRESSWIDTH = 32;
|
||||
parameter FIFODEPTH = 32; // must be at least twice MAXBURSTCOUNT in order to be efficient
|
||||
parameter FIFODEPTH_LOG2 = 5;
|
||||
parameter FIFOUSEMEMORY = 1; // set to 0 to use LEs instead
|
||||
|
||||
|
||||
|
||||
input clk;
|
||||
input reset;
|
||||
|
||||
// control inputs and outputs
|
||||
input control_fixed_location; // this only makes sense to enable when MAXBURSTCOUNT = 1
|
||||
input [ADDRESSWIDTH-1:0] control_write_base;
|
||||
input [ADDRESSWIDTH-1:0] control_write_length;
|
||||
input control_go;
|
||||
output wire control_done;
|
||||
|
||||
// user logic inputs and outputs
|
||||
input user_write_buffer;
|
||||
input [DATAWIDTH-1:0] user_buffer_data;
|
||||
output wire user_buffer_full;
|
||||
|
||||
// master inputs and outputs
|
||||
input master_waitrequest;
|
||||
output reg [ADDRESSWIDTH-1:0] master_address;
|
||||
output wire master_write;
|
||||
output wire [BYTEENABLEWIDTH-1:0] master_byteenable;
|
||||
output wire [DATAWIDTH-1:0] master_writedata;
|
||||
output reg [BURSTCOUNTWIDTH-1:0] master_burstcount;
|
||||
|
||||
// internal control signals
|
||||
reg control_fixed_location_d1;
|
||||
reg [ADDRESSWIDTH-1:0] length;
|
||||
wire final_short_burst_enable; // when the length is less than MAXBURSTCOUNT * # of bytes per word (BYTEENABLEWIDTH) (i.e. end of the transfer)
|
||||
wire final_short_burst_ready; // when there is enough data in the FIFO for the final burst
|
||||
wire [BURSTCOUNTWIDTH-1:0] burst_boundary_word_address; // represents the word offset within the burst boundary
|
||||
wire [BURSTCOUNTWIDTH-1:0] first_short_burst_count;
|
||||
wire [BURSTCOUNTWIDTH-1:0] final_short_burst_count;
|
||||
wire first_short_burst_enable; // when the transfer doesn't start on a burst boundary
|
||||
wire first_short_burst_ready; // when there is enough data in the FIFO to get the master back into burst alignment
|
||||
wire full_burst_ready; // when there is enough data in the FIFO for a full burst
|
||||
wire increment_address; // this increments the 'address' register when write is asserted and waitrequest is de-asserted
|
||||
wire burst_begin; // used to register the registers 'burst_address' and 'burst_count_d1' as well as drive the master_address and burst_count muxes
|
||||
wire read_fifo;
|
||||
wire [FIFODEPTH_LOG2-1:0] fifo_used; // going to combined used with the full bit
|
||||
wire [BURSTCOUNTWIDTH-1:0] burst_count; // watermark of the FIFO, it has a latency of 2 cycles
|
||||
reg [BURSTCOUNTWIDTH-1:0] burst_counter;
|
||||
reg first_transfer; // need to keep track of the first burst so that we don't incorrectly increment the address
|
||||
|
||||
|
||||
|
||||
// registering the control_fixed_location bit
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin
|
||||
if (reset == 1)
|
||||
begin
|
||||
control_fixed_location_d1 <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (control_go == 1)
|
||||
begin
|
||||
control_fixed_location_d1 <= control_fixed_location;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// set when control_go fires, and reset once the first burst starts
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin
|
||||
if (reset == 1)
|
||||
begin
|
||||
first_transfer <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (control_go == 1)
|
||||
begin
|
||||
first_transfer <= 1;
|
||||
end
|
||||
else if (burst_begin == 1)
|
||||
begin
|
||||
first_transfer <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// master address (held constant during burst)
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin
|
||||
if (reset == 1)
|
||||
begin
|
||||
master_address <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (control_go == 1)
|
||||
begin
|
||||
master_address <= control_write_base;
|
||||
end
|
||||
else if ((first_transfer == 0) & (burst_begin == 1) & (control_fixed_location_d1 == 0))
|
||||
begin
|
||||
master_address <= master_address + (master_burstcount * BYTEENABLEWIDTH); // we don't want address + BYTEENABLEWIDTH for the first access
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// master length logic
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin
|
||||
if (reset == 1)
|
||||
begin
|
||||
length <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (control_go == 1)
|
||||
begin
|
||||
length <= control_write_length;
|
||||
end
|
||||
else if (increment_address == 1)
|
||||
begin
|
||||
length <= length - BYTEENABLEWIDTH; // always performing word size accesses
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
// register the master burstcount (held constant during burst)
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin
|
||||
if (reset == 1)
|
||||
begin
|
||||
master_burstcount <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (burst_begin == 1)
|
||||
begin
|
||||
master_burstcount <= burst_count;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
// burst counter. This is set to the burst count being posted then counts down when each word
|
||||
// of data goes out. If it reaches 0 (i.e. not reloaded after 1) then the master stalls due to
|
||||
// a lack of data to post a new burst.
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin
|
||||
if (reset == 1)
|
||||
begin
|
||||
burst_counter <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (control_go == 1)
|
||||
begin
|
||||
burst_counter <= 0;
|
||||
end
|
||||
else if (burst_begin == 1)
|
||||
begin
|
||||
burst_counter <= burst_count;
|
||||
end
|
||||
else if (increment_address == 1) // decrements each write, burst_counter will only hit 0 if burst begin doesn't fire on the next cycle
|
||||
begin
|
||||
burst_counter <= burst_counter - 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
// burst boundaries are on the master "width * maximum burst count". The burst boundary word address will be used to determine how far off the boundary the transfer starts from.
|
||||
assign burst_boundary_word_address = ((master_address / BYTEENABLEWIDTH) & (MAXBURSTCOUNT - 1));
|
||||
|
||||
// first short burst enable will only be active on the first transfer (if applicable). It will either post the amount of words remaining to reach the end of the burst
|
||||
// boundary or post the remainder of the transfer whichever is shorter. If the transfer is very short and not aligned on a burst boundary then the same logic as the final short transfer is used
|
||||
assign first_short_burst_enable = (burst_boundary_word_address != 0) & (first_transfer == 1);
|
||||
assign first_short_burst_count = ((burst_boundary_word_address & 1'b1) == 1'b1)? 1 : // if the burst boundary isn't a multiple of 2 then must post a burst of 1 to get to a multiple of 2 for the next burst
|
||||
(((MAXBURSTCOUNT - burst_boundary_word_address) < (length / BYTEENABLEWIDTH))?
|
||||
(MAXBURSTCOUNT - burst_boundary_word_address) : final_short_burst_count);
|
||||
assign first_short_burst_ready = (fifo_used > first_short_burst_count) | ((fifo_used == first_short_burst_count) & (burst_counter == 0));
|
||||
|
||||
// when there isn't enough data for a full burst at the end of the transfer a short burst is sent out instead
|
||||
assign final_short_burst_enable = (length < (MAXBURSTCOUNT * BYTEENABLEWIDTH));
|
||||
assign final_short_burst_count = (length/BYTEENABLEWIDTH);
|
||||
assign final_short_burst_ready = (fifo_used > final_short_burst_count) | ((fifo_used == final_short_burst_count) & (burst_counter == 0)); // this will add a one cycle stall between bursts, since fifo_used has a cycle of latency, this only affects the last burst
|
||||
|
||||
// since the fifo has a latency of 1 we need to make sure we don't under flow
|
||||
assign full_burst_ready = (fifo_used > MAXBURSTCOUNT) | ((fifo_used == MAXBURSTCOUNT) & (burst_counter == 0)); // when fifo used watermark equals the burst count the statemachine must stall for one cycle, this will make sure that when a burst begins there really is enough data present in the FIFO
|
||||
|
||||
|
||||
assign master_byteenable = -1; // all ones, always performing word size accesses
|
||||
assign control_done = (length == 0);
|
||||
assign master_write = (control_done == 0) & (burst_counter != 0); // burst_counter = 0 means the transfer is done, or not enough data in the fifo for a new burst
|
||||
|
||||
// fifo controls and the burst_begin responsible for timing most of the circuit, burst_begin starts the writing statemachine
|
||||
assign burst_begin = (((first_short_burst_enable == 1) & (first_short_burst_ready == 1))
|
||||
| ((final_short_burst_enable == 1) & (final_short_burst_ready == 1))
|
||||
| (full_burst_ready == 1))
|
||||
& (control_done == 0) // since the FIFO can have data before the master starts we need to disable this bit from firing when length = 0
|
||||
& ((burst_counter == 0) | ((burst_counter == 1) & (master_waitrequest == 0) & (length > (MAXBURSTCOUNT * BYTEENABLEWIDTH)))); // need to make a short final burst doesn't start right after a full burst completes.
|
||||
|
||||
assign burst_count = (first_short_burst_enable == 1)? first_short_burst_count : // alignment correction gets priority, if the transfer is short and unaligned this will cover both
|
||||
(final_short_burst_enable == 1)? final_short_burst_count : MAXBURSTCOUNT;
|
||||
|
||||
assign increment_address = (master_write == 1) & (master_waitrequest == 0); // writing is occuring without wait states
|
||||
assign read_fifo = increment_address;
|
||||
|
||||
|
||||
|
||||
// write data feed by user logic
|
||||
scfifo the_user_to_master_fifo (
|
||||
.aclr (reset),
|
||||
.usedw (fifo_used),
|
||||
.clock (clk),
|
||||
.data (user_buffer_data),
|
||||
.almost_full (user_buffer_full),
|
||||
.q (master_writedata),
|
||||
.rdreq (read_fifo),
|
||||
.wrreq (user_write_buffer)
|
||||
);
|
||||
defparam the_user_to_master_fifo.lpm_width = DATAWIDTH;
|
||||
defparam the_user_to_master_fifo.lpm_numwords = FIFODEPTH;
|
||||
defparam the_user_to_master_fifo.lpm_showahead = "ON";
|
||||
defparam the_user_to_master_fifo.almost_full_value = (FIFODEPTH - 2);
|
||||
defparam the_user_to_master_fifo.use_eab = (FIFOUSEMEMORY == 1)? "ON" : "OFF";
|
||||
defparam the_user_to_master_fifo.add_ram_output_register = "OFF"; // makes timing the burst begin single simplier
|
||||
defparam the_user_to_master_fifo.underflow_checking = "OFF";
|
||||
defparam the_user_to_master_fifo.overflow_checking = "OFF";
|
||||
|
||||
endmodule
|
211
avalon_mm_master_templates/custom_master.v
Normal file
211
avalon_mm_master_templates/custom_master.v
Normal file
@ -0,0 +1,211 @@
|
||||
/*
|
||||
This file is a simple top level that will generate one of four types of
|
||||
Avalon-MM master. As a result all the ports must be declared and it will be
|
||||
up to the component .tcl file to stub unused signals.
|
||||
*/
|
||||
|
||||
// altera message_off 10034
|
||||
|
||||
module custom_master (
|
||||
clk,
|
||||
reset,
|
||||
|
||||
// control inputs and outputs
|
||||
control_fixed_location,
|
||||
control_read_base,
|
||||
control_read_length,
|
||||
control_write_base,
|
||||
control_write_length,
|
||||
control_go,
|
||||
control_done,
|
||||
control_early_done,
|
||||
|
||||
// user logic inputs and outputs
|
||||
user_read_buffer,
|
||||
user_write_buffer,
|
||||
user_buffer_input_data,
|
||||
user_buffer_output_data,
|
||||
user_data_available,
|
||||
user_buffer_full,
|
||||
|
||||
// master inputs and outputs
|
||||
master_address,
|
||||
master_read,
|
||||
master_write,
|
||||
master_byteenable,
|
||||
master_readdata,
|
||||
master_readdatavalid,
|
||||
master_writedata,
|
||||
master_burstcount,
|
||||
master_waitrequest
|
||||
);
|
||||
|
||||
parameter MASTER_DIRECTION = 0; // 0 for read master, 1 for write master
|
||||
parameter DATA_WIDTH = 32;
|
||||
parameter MEMORY_BASED_FIFO = 1; // 0 for LE/ALUT FIFOs, 1 for memory FIFOs (highly recommend 1)
|
||||
parameter FIFO_DEPTH = 32;
|
||||
parameter FIFO_DEPTH_LOG2 = 5;
|
||||
parameter ADDRESS_WIDTH = 32;
|
||||
parameter BURST_CAPABLE = 0; // 1 to enable burst, 0 to disable it
|
||||
parameter MAXIMUM_BURST_COUNT = 2;
|
||||
parameter BURST_COUNT_WIDTH = 2;
|
||||
|
||||
|
||||
input clk;
|
||||
input reset;
|
||||
|
||||
// control inputs and outputs
|
||||
input control_fixed_location;
|
||||
input [ADDRESS_WIDTH-1:0] control_read_base; // for read master
|
||||
input [ADDRESS_WIDTH-1:0] control_read_length; // for read master
|
||||
input [ADDRESS_WIDTH-1:0] control_write_base; // for write master
|
||||
input [ADDRESS_WIDTH-1:0] control_write_length; // for write master
|
||||
input control_go;
|
||||
output wire control_done;
|
||||
output wire control_early_done; // for read master
|
||||
|
||||
// user logic inputs and outputs
|
||||
input user_read_buffer; // for read master
|
||||
input user_write_buffer; // for write master
|
||||
input [DATA_WIDTH-1:0] user_buffer_input_data; // for write master
|
||||
output wire [DATA_WIDTH-1:0] user_buffer_output_data; // for read master
|
||||
output wire user_data_available; // for read master
|
||||
output wire user_buffer_full; // for write master
|
||||
|
||||
// master inputs and outputs
|
||||
output wire [ADDRESS_WIDTH-1:0] master_address;
|
||||
output wire master_read; // for read master
|
||||
output wire master_write; // for write master
|
||||
output wire [(DATA_WIDTH/8)-1:0] master_byteenable;
|
||||
input [DATA_WIDTH-1:0] master_readdata; // for read master
|
||||
input master_readdatavalid; // for read master
|
||||
output wire [DATA_WIDTH-1:0] master_writedata; // for write master
|
||||
output wire [BURST_COUNT_WIDTH-1:0] master_burstcount; // for bursting read and write masters
|
||||
input master_waitrequest;
|
||||
|
||||
|
||||
generate // big generate if statement to select the approprate master depending on the direction and burst parameters
|
||||
if(MASTER_DIRECTION == 0)
|
||||
begin
|
||||
if(BURST_CAPABLE == 1)
|
||||
begin
|
||||
burst_read_master a_burst_read_master(
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.control_fixed_location (control_fixed_location),
|
||||
.control_read_base (control_read_base),
|
||||
.control_read_length (control_read_length),
|
||||
.control_go (control_go),
|
||||
.control_done (control_done),
|
||||
.control_early_done (control_early_done),
|
||||
.user_read_buffer (user_read_buffer),
|
||||
.user_buffer_data (user_buffer_output_data),
|
||||
.user_data_available (user_data_available),
|
||||
.master_address (master_address),
|
||||
.master_read (master_read),
|
||||
.master_byteenable (master_byteenable),
|
||||
.master_readdata (master_readdata),
|
||||
.master_readdatavalid (master_readdatavalid),
|
||||
.master_burstcount (master_burstcount),
|
||||
.master_waitrequest (master_waitrequest)
|
||||
);
|
||||
defparam a_burst_read_master.DATAWIDTH = DATA_WIDTH;
|
||||
defparam a_burst_read_master.MAXBURSTCOUNT = MAXIMUM_BURST_COUNT;
|
||||
defparam a_burst_read_master.BURSTCOUNTWIDTH = BURST_COUNT_WIDTH;
|
||||
defparam a_burst_read_master.BYTEENABLEWIDTH = DATA_WIDTH/8;
|
||||
defparam a_burst_read_master.ADDRESSWIDTH = ADDRESS_WIDTH;
|
||||
defparam a_burst_read_master.FIFODEPTH = FIFO_DEPTH;
|
||||
defparam a_burst_read_master.FIFODEPTH_LOG2 = FIFO_DEPTH_LOG2;
|
||||
defparam a_burst_read_master.FIFOUSEMEMORY = MEMORY_BASED_FIFO;
|
||||
end
|
||||
else
|
||||
begin
|
||||
latency_aware_read_master a_latency_aware_read_master(
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.control_fixed_location (control_fixed_location),
|
||||
.control_read_base (control_read_base),
|
||||
.control_read_length (control_read_length),
|
||||
.control_go (control_go),
|
||||
.control_done (control_done),
|
||||
.control_early_done (control_early_done),
|
||||
.user_read_buffer (user_read_buffer),
|
||||
.user_buffer_data (user_buffer_output_data),
|
||||
.user_data_available (user_data_available),
|
||||
.master_address (master_address),
|
||||
.master_read (master_read),
|
||||
.master_byteenable (master_byteenable),
|
||||
.master_readdata (master_readdata),
|
||||
.master_readdatavalid (master_readdatavalid),
|
||||
.master_waitrequest (master_waitrequest)
|
||||
);
|
||||
defparam a_latency_aware_read_master.DATAWIDTH = DATA_WIDTH;
|
||||
defparam a_latency_aware_read_master.BYTEENABLEWIDTH = DATA_WIDTH/8;
|
||||
defparam a_latency_aware_read_master.ADDRESSWIDTH = ADDRESS_WIDTH;
|
||||
defparam a_latency_aware_read_master.FIFODEPTH = FIFO_DEPTH;
|
||||
defparam a_latency_aware_read_master.FIFODEPTH_LOG2 = FIFO_DEPTH_LOG2;
|
||||
defparam a_latency_aware_read_master.FIFOUSEMEMORY = MEMORY_BASED_FIFO;
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
if(BURST_CAPABLE == 1)
|
||||
begin
|
||||
burst_write_master a_burst_write_master(
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.control_fixed_location (control_fixed_location),
|
||||
.control_write_base (control_write_base),
|
||||
.control_write_length (control_write_length),
|
||||
.control_go (control_go),
|
||||
.control_done (control_done),
|
||||
.user_write_buffer (user_write_buffer),
|
||||
.user_buffer_data (user_buffer_input_data),
|
||||
.user_buffer_full (user_buffer_full),
|
||||
.master_address (master_address),
|
||||
.master_write (master_write),
|
||||
.master_byteenable (master_byteenable),
|
||||
.master_writedata (master_writedata),
|
||||
.master_burstcount (master_burstcount),
|
||||
.master_waitrequest (master_waitrequest)
|
||||
);
|
||||
defparam a_burst_write_master.DATAWIDTH = DATA_WIDTH;
|
||||
defparam a_burst_write_master.MAXBURSTCOUNT = MAXIMUM_BURST_COUNT;
|
||||
defparam a_burst_write_master.BURSTCOUNTWIDTH = BURST_COUNT_WIDTH;
|
||||
defparam a_burst_write_master.BYTEENABLEWIDTH = DATA_WIDTH/8;
|
||||
defparam a_burst_write_master.ADDRESSWIDTH = ADDRESS_WIDTH;
|
||||
defparam a_burst_write_master.FIFODEPTH = FIFO_DEPTH;
|
||||
defparam a_burst_write_master.FIFODEPTH_LOG2 = FIFO_DEPTH_LOG2;
|
||||
defparam a_burst_write_master.FIFOUSEMEMORY = MEMORY_BASED_FIFO;
|
||||
end
|
||||
else
|
||||
begin
|
||||
write_master a_write_master(
|
||||
.clk (clk),
|
||||
.reset (reset),
|
||||
.control_fixed_location (control_fixed_location),
|
||||
.control_write_base (control_write_base),
|
||||
.control_write_length (control_write_length),
|
||||
.control_go (control_go),
|
||||
.control_done (control_done),
|
||||
.user_write_buffer (user_write_buffer),
|
||||
.user_buffer_data (user_buffer_input_data),
|
||||
.user_buffer_full (user_buffer_full),
|
||||
.master_address (master_address),
|
||||
.master_write (master_write),
|
||||
.master_byteenable (master_byteenable),
|
||||
.master_writedata (master_writedata),
|
||||
.master_waitrequest (master_waitrequest)
|
||||
);
|
||||
defparam a_write_master.DATAWIDTH = DATA_WIDTH;
|
||||
defparam a_write_master.BYTEENABLEWIDTH = DATA_WIDTH/8;
|
||||
defparam a_write_master.ADDRESSWIDTH = ADDRESS_WIDTH;
|
||||
defparam a_write_master.FIFODEPTH = FIFO_DEPTH;
|
||||
defparam a_write_master.FIFODEPTH_LOG2 = FIFO_DEPTH_LOG2;
|
||||
defparam a_write_master.FIFOUSEMEMORY = MEMORY_BASED_FIFO;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
endmodule
|
291
avalon_mm_master_templates/custom_masters_hw.tcl
Normal file
291
avalon_mm_master_templates/custom_masters_hw.tcl
Normal file
@ -0,0 +1,291 @@
|
||||
# TCL File Generated by Component Editor 8.0
|
||||
# Sat May 31 20:41:17 PDT 2008
|
||||
# DO NOT MODIFY
|
||||
|
||||
|
||||
|
||||
# +-----------------------------------
|
||||
# | module burst_read_master
|
||||
# |
|
||||
set_module_property DESCRIPTION "Custom Avalon-MM Masters"
|
||||
set_module_property NAME master_template
|
||||
set_module_property VERSION 1.0
|
||||
set_module_property GROUP "Templates"
|
||||
set_module_property AUTHOR JCJB
|
||||
set_module_property ICON_PATH ALTERA_LOGO_ANIM.gif
|
||||
set_module_property DISPLAY_NAME master_template
|
||||
set_module_property TOP_LEVEL_HDL_FILE custom_master.v
|
||||
set_module_property TOP_LEVEL_HDL_MODULE custom_master
|
||||
set_module_property INSTANTIATE_IN_SYSTEM_MODULE true
|
||||
set_module_property EDITABLE false
|
||||
set_module_property SIMULATION_MODEL_IN_VERILOG false
|
||||
set_module_property SIMULATION_MODEL_IN_VHDL false
|
||||
set_module_property SIMULATION_MODEL_HAS_TULIPS false
|
||||
set_module_property SIMULATION_MODEL_IS_OBFUSCATED false
|
||||
# |
|
||||
# +-----------------------------------
|
||||
|
||||
|
||||
set_module_property ELABORATION_CALLBACK elaborate_me
|
||||
set_module_property VALIDATION_CALLBACK validate_me
|
||||
|
||||
|
||||
# +-----------------------------------
|
||||
# | files
|
||||
# |
|
||||
add_file custom_master.v {SYNTHESIS SIMULATION}
|
||||
add_file burst_write_master.v {SYNTHESIS SIMULATION}
|
||||
add_file burst_read_master.v {SYNTHESIS SIMULATION}
|
||||
add_file write_master.v {SYNTHESIS SIMULATION}
|
||||
add_file latency_aware_read_master.v {SYNTHESIS SIMULATION}
|
||||
# |
|
||||
# +-----------------------------------
|
||||
|
||||
# +-----------------------------------
|
||||
# | parameters
|
||||
# |
|
||||
|
||||
# Avalon Master Settings
|
||||
add_parameter MASTER_DIRECTION Integer 0 "Sets the master direction between read (0) and write (1) transfers"
|
||||
set_parameter_property MASTER_DIRECTION VISIBLE true
|
||||
set_parameter_property MASTER_DIRECTION DISPLAY_NAME "Master Direction"
|
||||
set_parameter_property MASTER_DIRECTION GROUP "Avalon-MM Master Properties"
|
||||
set_parameter_property MASTER_DIRECTION AFFECTS_PORT_WIDTHS true
|
||||
set_parameter_property MASTER_DIRECTION ALLOWED_RANGES {"0:Read" "1:Write"}
|
||||
|
||||
add_parameter DATA_WIDTH Integer 32 "Width of the data path"
|
||||
set_parameter_property DATA_WIDTH VISIBLE true
|
||||
set_parameter_property DATA_WIDTH DISPLAY_NAME "Data Width"
|
||||
set_parameter_property DATA_WIDTH GROUP "Avalon-MM Master Properties"
|
||||
set_parameter_property DATA_WIDTH AFFECTS_PORT_WIDTHS true
|
||||
set_parameter_property DATA_WIDTH ALLOWED_RANGES {8 16 32 64 128 256 512 1024}
|
||||
|
||||
add_parameter ADDRESS_WIDTH Integer "32" "Address Width"
|
||||
set_parameter_property ADDRESS_WIDTH VISIBLE true
|
||||
set_parameter_property ADDRESS_WIDTH DISPLAY_NAME "Address Width"
|
||||
set_parameter_property ADDRESS_WIDTH GROUP "Avalon-MM Master Properties"
|
||||
set_parameter_property ADDRESS_WIDTH AFFECTS_PORT_WIDTHS true
|
||||
set_parameter_property ADDRESS_WIDTH ALLOWED_RANGES {32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 14 13 12 11 10 9 8 7 6 5 4}
|
||||
|
||||
|
||||
# Burst Settings
|
||||
add_parameter BURST_CAPABLE Integer 0 "Enable bursting"
|
||||
set_parameter_property BURST_CAPABLE VISIBLE true
|
||||
set_parameter_property BURST_CAPABLE DISPLAY_NAME "Burst Capable"
|
||||
set_parameter_property BURST_CAPABLE GROUP "Burst Properties"
|
||||
set_parameter_property BURST_CAPABLE AFFECTS_PORT_WIDTHS true
|
||||
set_parameter_property BURST_CAPABLE ALLOWED_RANGES {"0:Disabled" "1:Enabled"}
|
||||
|
||||
add_parameter MAXIMUM_BURST_COUNT Integer "2" "Maximum Burst Count"
|
||||
set_parameter_property MAXIMUM_BURST_COUNT VISIBLE true
|
||||
set_parameter_property MAXIMUM_BURST_COUNT DISPLAY_NAME "Maximum Burst Count"
|
||||
set_parameter_property MAXIMUM_BURST_COUNT GROUP "Burst Properties"
|
||||
set_parameter_property MAXIMUM_BURST_COUNT AFFECTS_PORT_WIDTHS false
|
||||
set_parameter_property MAXIMUM_BURST_COUNT ALLOWED_RANGES {1 2 4 8 16 32 64 128}
|
||||
|
||||
add_parameter BURST_COUNT_WIDTH Integer "2" "Enable bursting"
|
||||
set_parameter_property BURST_COUNT_WIDTH VISIBLE false
|
||||
set_parameter_property BURST_COUNT_WIDTH DISPLAY_NAME "Burst Count Width"
|
||||
set_parameter_property BURST_COUNT_WIDTH GROUP "Burst Properties"
|
||||
set_parameter_property BURST_COUNT_WIDTH AFFECTS_PORT_WIDTHS true
|
||||
set_parameter_property BURST_COUNT_WIDTH ALLOWED_RANGES {1:8}
|
||||
|
||||
|
||||
# Other Settings
|
||||
add_parameter FIFO_DEPTH Integer "32" "FIFO depth"
|
||||
set_parameter_property FIFO_DEPTH VISIBLE true
|
||||
set_parameter_property FIFO_DEPTH DISPLAY_NAME "FIFO Depth"
|
||||
set_parameter_property FIFO_DEPTH GROUP "Other Properties"
|
||||
set_parameter_property FIFO_DEPTH AFFECTS_PORT_WIDTHS false
|
||||
set_parameter_property FIFO_DEPTH ALLOWED_RANGES {4 8 16 32 64 128 256}
|
||||
|
||||
add_parameter FIFO_DEPTH_LOG2 Integer "5" "log2(FIFO Depth)"
|
||||
set_parameter_property FIFO_DEPTH_LOG2 VISIBLE false
|
||||
set_parameter_property FIFO_DEPTH_LOG2 DISPLAY_NAME "log2(FIFO Depth)"
|
||||
set_parameter_property FIFO_DEPTH_LOG2 GROUP "Other Properties"
|
||||
set_parameter_property FIFO_DEPTH_LOG2 AFFECTS_PORT_WIDTHS false
|
||||
set_parameter_property FIFO_DEPTH_LOG2 ALLOWED_RANGES {2:8}
|
||||
|
||||
add_parameter MEMORY_BASED_FIFO Integer 1 "Select false if you want register based (0) FIFO instead of memory (1)"
|
||||
set_parameter_property MEMORY_BASED_FIFO VISIBLE true
|
||||
set_parameter_property MEMORY_BASED_FIFO DISPLAY_NAME "Memory based FIFO"
|
||||
set_parameter_property MEMORY_BASED_FIFO GROUP "Other Properties"
|
||||
set_parameter_property MEMORY_BASED_FIFO AFFECTS_PORT_WIDTHS false
|
||||
set_parameter_property MEMORY_BASED_FIFO ALLOWED_RANGES {"1:Memory" "0:Logic"}
|
||||
# |
|
||||
# +-----------------------------------
|
||||
|
||||
# +-----------------------------------
|
||||
# | connection point clock_reset
|
||||
# |
|
||||
add_interface clock_reset clock end
|
||||
set_interface_property clock_reset ptfSchematicName ""
|
||||
|
||||
add_interface_port clock_reset clk clk Input 1
|
||||
add_interface_port clock_reset reset reset Input 1
|
||||
# |
|
||||
# +-----------------------------------
|
||||
|
||||
# +-----------------------------------
|
||||
# | connection point avalon_master
|
||||
# |
|
||||
add_interface avalon_master avalon start
|
||||
set_interface_property avalon_master linewrapBursts false
|
||||
set_interface_property avalon_master adaptsTo ""
|
||||
set_interface_property avalon_master doStreamReads false
|
||||
set_interface_property avalon_master doStreamWrites false
|
||||
set_interface_property avalon_master burstOnBurstBoundariesOnly false
|
||||
|
||||
set_interface_property avalon_master ASSOCIATED_CLOCK clock_reset
|
||||
|
||||
add_interface_port avalon_master master_address address Output -1
|
||||
add_interface_port avalon_master master_read read Output 1
|
||||
add_interface_port avalon_master master_write write Output 1
|
||||
add_interface_port avalon_master master_byteenable byteenable Output -1
|
||||
add_interface_port avalon_master master_readdata readdata Input -1
|
||||
add_interface_port avalon_master master_readdatavalid readdatavalid Input 1
|
||||
add_interface_port avalon_master master_writedata writedata Output -1
|
||||
add_interface_port avalon_master master_burstcount burstcount Output -1
|
||||
add_interface_port avalon_master master_waitrequest waitrequest Input 1
|
||||
# |
|
||||
# +-----------------------------------
|
||||
|
||||
# +-----------------------------------
|
||||
# | connection point control
|
||||
# |
|
||||
add_interface control conduit end
|
||||
|
||||
set_interface_property control ASSOCIATED_CLOCK clock_reset
|
||||
|
||||
add_interface_port control control_fixed_location export Input 1
|
||||
add_interface_port control control_read_base export Input -1
|
||||
add_interface_port control control_write_base export Input -1
|
||||
add_interface_port control control_read_length export Input -1
|
||||
add_interface_port control control_write_length export Input -1
|
||||
add_interface_port control control_go export Input 1
|
||||
add_interface_port control control_done export Output 1
|
||||
add_interface_port control control_early_done export Output 1
|
||||
# |
|
||||
# +-----------------------------------
|
||||
|
||||
# +-----------------------------------
|
||||
# | connection point user
|
||||
# |
|
||||
add_interface user conduit end
|
||||
|
||||
set_interface_property user ASSOCIATED_CLOCK clock_reset
|
||||
|
||||
add_interface_port user user_read_buffer export Input 1
|
||||
add_interface_port user user_buffer_output_data export Output -1
|
||||
add_interface_port user user_data_available export Output 1
|
||||
add_interface_port user user_write_buffer export Input 1
|
||||
add_interface_port user user_buffer_input_data export Input -1
|
||||
add_interface_port user user_buffer_full export Output 1
|
||||
# |
|
||||
# +-----------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
proc elaborate_me {} {
|
||||
|
||||
# set all the new port widths
|
||||
set the_data_width [get_parameter_value DATA_WIDTH]
|
||||
set the_byteenable_width [expr {$the_data_width / 8} ]
|
||||
set the_address_width [get_parameter_value ADDRESS_WIDTH]
|
||||
set the_burst_count_width [get_parameter_value BURST_COUNT_WIDTH]
|
||||
|
||||
|
||||
set_port_property control_read_base WIDTH $the_address_width
|
||||
set_port_property control_read_length WIDTH $the_address_width
|
||||
set_port_property control_write_base WIDTH $the_address_width
|
||||
set_port_property control_write_length WIDTH $the_address_width
|
||||
set_port_property user_buffer_input_data WIDTH $the_data_width
|
||||
set_port_property user_buffer_output_data WIDTH $the_data_width
|
||||
set_port_property master_address WIDTH $the_address_width
|
||||
set_port_property master_byteenable WIDTH $the_byteenable_width
|
||||
set_port_property master_readdata WIDTH $the_data_width
|
||||
set_port_property master_writedata WIDTH $the_data_width
|
||||
set_port_property master_burstcount WIDTH $the_burst_count_width
|
||||
|
||||
|
||||
# determine the master direction and burst capabilities
|
||||
set the_master_direction [get_parameter_value MASTER_DIRECTION]
|
||||
set the_burst_capable [get_parameter_value BURST_CAPABLE]
|
||||
|
||||
|
||||
# switch between read and write master signals (excluding burstcount)
|
||||
if { $the_master_direction == 0 } {
|
||||
set_port_property control_read_base TERMINATION false
|
||||
set_port_property control_read_length TERMINATION false
|
||||
set_port_property control_write_base TERMINATION true
|
||||
set_port_property control_write_length TERMINATION true
|
||||
set_port_property control_early_done TERMINATION false
|
||||
set_port_property user_read_buffer TERMINATION false
|
||||
set_port_property user_write_buffer TERMINATION true
|
||||
set_port_property user_buffer_input_data TERMINATION true
|
||||
set_port_property user_buffer_output_data TERMINATION false
|
||||
set_port_property user_data_available TERMINATION false
|
||||
set_port_property user_buffer_full TERMINATION true
|
||||
set_port_property master_read TERMINATION false
|
||||
set_port_property master_write TERMINATION true
|
||||
set_port_property master_readdata TERMINATION false
|
||||
set_port_property master_readdatavalid TERMINATION false
|
||||
set_port_property master_writedata TERMINATION true
|
||||
} else {
|
||||
set_port_property control_read_base TERMINATION true
|
||||
set_port_property control_read_length TERMINATION true
|
||||
set_port_property control_write_base TERMINATION false
|
||||
set_port_property control_write_length TERMINATION false
|
||||
set_port_property control_early_done TERMINATION true
|
||||
set_port_property user_read_buffer TERMINATION true
|
||||
set_port_property user_write_buffer TERMINATION false
|
||||
set_port_property user_buffer_input_data TERMINATION false
|
||||
set_port_property user_buffer_output_data TERMINATION true
|
||||
set_port_property user_data_available TERMINATION true
|
||||
set_port_property user_buffer_full TERMINATION false
|
||||
set_port_property master_read TERMINATION true
|
||||
set_port_property master_write TERMINATION false
|
||||
set_port_property master_readdata TERMINATION true
|
||||
set_port_property master_readdatavalid TERMINATION true
|
||||
set_port_property master_writedata TERMINATION false
|
||||
}
|
||||
|
||||
# enable/disable the burstcount signal
|
||||
if { $the_burst_capable == 0 } {
|
||||
set_port_property master_burstcount TERMINATION true
|
||||
} else {
|
||||
set_port_property master_burstcount TERMINATION false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
proc validate_me {} {
|
||||
|
||||
# read in all the parameter that matter for validation
|
||||
set the_burst_capable [get_parameter_value BURST_CAPABLE]
|
||||
set the_maximum_burst_count [get_parameter_value MAXIMUM_BURST_COUNT]
|
||||
set the_fifo_depth [get_parameter_value FIFO_DEPTH]
|
||||
|
||||
# when burst is enabled check to make sure FIFO depth is at least twice as large (also enable/disable burst count)
|
||||
if { $the_burst_capable == 1 } {
|
||||
set_parameter_property MAXIMUM_BURST_COUNT ENABLED true
|
||||
if { $the_fifo_depth < [expr {$the_maximum_burst_count * 2}] } {
|
||||
send_message Error "The FIFO Depth must be at least twice as large as Maximum Burst Count."
|
||||
}
|
||||
} else {
|
||||
set_parameter_property MAXIMUM_BURST_COUNT ENABLED false
|
||||
}
|
||||
|
||||
|
||||
set the_burst_count [get_parameter_value MAXIMUM_BURST_COUNT]
|
||||
set the_burst_count_width [expr {(log($the_burst_count) / log(2)) + 1}]
|
||||
|
||||
set the_fifo_depth [get_parameter_value FIFO_DEPTH]
|
||||
set the_fifo_depth_log2 [expr {log($the_fifo_depth) / log(2)}]
|
||||
|
||||
set_parameter_value BURST_COUNT_WIDTH $the_burst_count_width
|
||||
set_parameter_value FIFO_DEPTH_LOG2 $the_fifo_depth_log2
|
||||
}
|
247
avalon_mm_master_templates/latency_aware_read_master.v
Normal file
247
avalon_mm_master_templates/latency_aware_read_master.v
Normal file
@ -0,0 +1,247 @@
|
||||
/*
|
||||
Legal Notice: (C)2007 Altera Corporation. All rights reserved. Your
|
||||
use of Altera Corporation's design tools, logic functions and other
|
||||
software and tools, and its AMPP partner logic functions, and any
|
||||
output files any of the foregoing (including device programming or
|
||||
simulation files), and any associated documentation or information are
|
||||
expressly subject to the terms and conditions of the Altera Program
|
||||
License Subscription Agreement or other applicable license agreement,
|
||||
including, without limitation, that your use is for the sole purpose
|
||||
of programming logic devices manufactured by Altera and sold by Altera
|
||||
or its authorized distributors. Please refer to the applicable
|
||||
agreement for further details.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Author: JCJB
|
||||
Date: 11/04/2007
|
||||
|
||||
This latency aware read master is passed a word aligned address, length in bytes,
|
||||
and a 'go' bit. The master will continue to post reads until the length register
|
||||
reaches a value of zero. When all the reads return the done bit will be asserted.
|
||||
|
||||
To use this master you must simply drive the control signals into this block,
|
||||
and also read the data from the exposed read FIFO. To read from the exposed FIFO
|
||||
use the 'user_read_buffer' signal to pop data from the FIFO 'user_buffer_data'.
|
||||
The signal 'user_data_available' is asserted whenever data is available from the
|
||||
exposed FIFO.
|
||||
|
||||
*/
|
||||
|
||||
// altera message_off 10230
|
||||
|
||||
|
||||
module latency_aware_read_master (
|
||||
clk,
|
||||
reset,
|
||||
|
||||
// control inputs and outputs
|
||||
control_fixed_location,
|
||||
control_read_base,
|
||||
control_read_length,
|
||||
control_go,
|
||||
control_done,
|
||||
control_early_done,
|
||||
|
||||
// user logic inputs and outputs
|
||||
user_read_buffer,
|
||||
user_buffer_data,
|
||||
user_data_available,
|
||||
|
||||
// master inputs and outputs
|
||||
master_address,
|
||||
master_read,
|
||||
master_byteenable,
|
||||
master_readdata,
|
||||
master_readdatavalid,
|
||||
master_waitrequest
|
||||
);
|
||||
|
||||
parameter DATAWIDTH = 32;
|
||||
parameter BYTEENABLEWIDTH = 4;
|
||||
parameter ADDRESSWIDTH = 32;
|
||||
parameter FIFODEPTH = 32;
|
||||
parameter FIFODEPTH_LOG2 = 5;
|
||||
parameter FIFOUSEMEMORY = 1; // set to 0 to use LEs instead
|
||||
|
||||
input clk;
|
||||
input reset;
|
||||
|
||||
|
||||
// control inputs and outputs
|
||||
input control_fixed_location;
|
||||
input [ADDRESSWIDTH-1:0] control_read_base;
|
||||
input [ADDRESSWIDTH-1:0] control_read_length;
|
||||
input control_go;
|
||||
output wire control_done;
|
||||
output wire control_early_done; // don't use this unless you know what you are doing!
|
||||
|
||||
// user logic inputs and outputs
|
||||
input user_read_buffer;
|
||||
output wire [DATAWIDTH-1:0] user_buffer_data;
|
||||
output wire user_data_available;
|
||||
|
||||
// master inputs and outputs
|
||||
input master_waitrequest;
|
||||
input master_readdatavalid;
|
||||
input [DATAWIDTH-1:0] master_readdata;
|
||||
output wire [ADDRESSWIDTH-1:0] master_address;
|
||||
output wire master_read;
|
||||
output wire [BYTEENABLEWIDTH-1:0] master_byteenable;
|
||||
|
||||
// internal control signals
|
||||
reg control_fixed_location_d1;
|
||||
wire fifo_empty;
|
||||
reg [ADDRESSWIDTH-1:0] address;
|
||||
reg [ADDRESSWIDTH-1:0] length;
|
||||
reg [FIFODEPTH_LOG2-1:0] reads_pending;
|
||||
wire increment_address;
|
||||
wire too_many_pending_reads;
|
||||
reg too_many_pending_reads_d1;
|
||||
wire [FIFODEPTH_LOG2-1:0] fifo_used;
|
||||
|
||||
|
||||
|
||||
|
||||
// registering the control_fixed_location bit
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin
|
||||
if (reset == 1)
|
||||
begin
|
||||
control_fixed_location_d1 <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (control_go == 1)
|
||||
begin
|
||||
control_fixed_location_d1 <= control_fixed_location;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
// master address logic
|
||||
assign master_address = address;
|
||||
assign master_byteenable = -1; // all ones, always performing word size accesses
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin
|
||||
if (reset == 1)
|
||||
begin
|
||||
address <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if(control_go == 1)
|
||||
begin
|
||||
address <= control_read_base;
|
||||
end
|
||||
else if((increment_address == 1) & (control_fixed_location_d1 == 0))
|
||||
begin
|
||||
address <= address + BYTEENABLEWIDTH; // always performing word size accesses
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
// master length logic
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin
|
||||
if (reset == 1)
|
||||
begin
|
||||
length <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if(control_go == 1)
|
||||
begin
|
||||
length <= control_read_length;
|
||||
end
|
||||
else if(increment_address == 1)
|
||||
begin
|
||||
length <= length - BYTEENABLEWIDTH; // always performing word size accesses
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
// control logic
|
||||
assign too_many_pending_reads = (fifo_used + reads_pending) >= (FIFODEPTH - 4);
|
||||
assign master_read = (length != 0) & (too_many_pending_reads_d1 == 0);
|
||||
assign increment_address = (length != 0) & (too_many_pending_reads_d1 == 0) & (master_waitrequest == 0);
|
||||
assign control_done = (reads_pending == 0) & (length == 0); // master done posting reads and all reads have returned
|
||||
assign control_early_done = (length == 0); // if you need all the pending reads to return then use 'control_done' instead of this signal
|
||||
|
||||
|
||||
always @ (posedge clk)
|
||||
begin
|
||||
if (reset == 1)
|
||||
begin
|
||||
too_many_pending_reads_d1 <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
too_many_pending_reads_d1 <= too_many_pending_reads;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin
|
||||
if (reset == 1)
|
||||
begin
|
||||
reads_pending <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if(increment_address == 1)
|
||||
begin
|
||||
if(master_readdatavalid == 0)
|
||||
begin
|
||||
reads_pending <= reads_pending + 1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
reads_pending <= reads_pending; // a read was posted, but another returned
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
if(master_readdatavalid == 0)
|
||||
begin
|
||||
reads_pending <= reads_pending; // read was not posted and no read returned
|
||||
end
|
||||
else
|
||||
begin
|
||||
reads_pending <= reads_pending - 1; // read was not posted but a read returned
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// read data feeding user logic
|
||||
assign user_data_available = !fifo_empty;
|
||||
scfifo the_master_to_user_fifo (
|
||||
.aclr (reset),
|
||||
.clock (clk),
|
||||
.data (master_readdata),
|
||||
.empty (fifo_empty),
|
||||
.q (user_buffer_data),
|
||||
.rdreq (user_read_buffer),
|
||||
.usedw (fifo_used),
|
||||
.wrreq (master_readdatavalid)
|
||||
);
|
||||
defparam the_master_to_user_fifo.lpm_width = DATAWIDTH;
|
||||
defparam the_master_to_user_fifo.lpm_numwords = FIFODEPTH;
|
||||
defparam the_master_to_user_fifo.lpm_showahead = "ON";
|
||||
defparam the_master_to_user_fifo.use_eab = (FIFOUSEMEMORY == 1)? "ON" : "OFF";
|
||||
defparam the_master_to_user_fifo.add_ram_output_register = "OFF";
|
||||
defparam the_master_to_user_fifo.underflow_checking = "OFF";
|
||||
defparam the_master_to_user_fifo.overflow_checking = "OFF";
|
||||
|
||||
endmodule
|
191
avalon_mm_master_templates/write_master.v
Normal file
191
avalon_mm_master_templates/write_master.v
Normal file
@ -0,0 +1,191 @@
|
||||
/*
|
||||
Legal Notice: (C)2007 Altera Corporation. All rights reserved. Your
|
||||
use of Altera Corporation's design tools, logic functions and other
|
||||
software and tools, and its AMPP partner logic functions, and any
|
||||
output files any of the foregoing (including device programming or
|
||||
simulation files), and any associated documentation or information are
|
||||
expressly subject to the terms and conditions of the Altera Program
|
||||
License Subscription Agreement or other applicable license agreement,
|
||||
including, without limitation, that your use is for the sole purpose
|
||||
of programming logic devices manufactured by Altera and sold by Altera
|
||||
or its authorized distributors. Please refer to the applicable
|
||||
agreement for further details.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Author: JCJB
|
||||
Date: 11/04/2007
|
||||
|
||||
This simple write master is passed a word aligned address, length in bytes,
|
||||
and a 'go' bit. The master will continue to post writes until the length register
|
||||
reaches zero. When the length register reaches zero the 'done' bit is asserted.
|
||||
|
||||
To use this master you must simply drive the control signals into this block,
|
||||
and also write the data to the exposed write FIFO. To read from the exposed FIFO
|
||||
use the 'user_write_buffer' signal to push data into the FIFO 'user_buffer_data'.
|
||||
The signal 'user_buffer_full' is asserted whenever the exposed buffer is full.
|
||||
You should not attempt to write data to the exposed FIFO if it is full.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
// altera message_off 10230
|
||||
|
||||
module write_master (
|
||||
clk,
|
||||
reset,
|
||||
|
||||
// control inputs and outputs
|
||||
control_fixed_location,
|
||||
control_write_base,
|
||||
control_write_length,
|
||||
control_go,
|
||||
control_done,
|
||||
|
||||
// user logic inputs and outputs
|
||||
user_write_buffer,
|
||||
user_buffer_data,
|
||||
user_buffer_full,
|
||||
|
||||
// master inputs and outputs
|
||||
master_address,
|
||||
master_write,
|
||||
master_byteenable,
|
||||
master_writedata,
|
||||
master_waitrequest
|
||||
);
|
||||
|
||||
|
||||
parameter DATAWIDTH = 32;
|
||||
parameter BYTEENABLEWIDTH = 4;
|
||||
parameter ADDRESSWIDTH = 32;
|
||||
parameter FIFODEPTH = 32;
|
||||
parameter FIFODEPTH_LOG2 = 5;
|
||||
parameter FIFOUSEMEMORY = 1; // set to 0 to use LEs instead
|
||||
|
||||
|
||||
|
||||
input clk;
|
||||
input reset;
|
||||
|
||||
// control inputs and outputs
|
||||
input control_fixed_location; // this only makes sense to enable when MAXBURSTCOUNT = 1
|
||||
input [ADDRESSWIDTH-1:0] control_write_base;
|
||||
input [ADDRESSWIDTH-1:0] control_write_length;
|
||||
input control_go;
|
||||
output wire control_done;
|
||||
|
||||
// user logic inputs and outputs
|
||||
input user_write_buffer;
|
||||
input [DATAWIDTH-1:0] user_buffer_data;
|
||||
output wire user_buffer_full;
|
||||
|
||||
// master inputs and outputs
|
||||
input master_waitrequest;
|
||||
output wire [ADDRESSWIDTH-1:0] master_address;
|
||||
output wire master_write;
|
||||
output wire [BYTEENABLEWIDTH-1:0] master_byteenable;
|
||||
output wire [DATAWIDTH-1:0] master_writedata;
|
||||
|
||||
|
||||
// internal control signals
|
||||
reg control_fixed_location_d1;
|
||||
reg [ADDRESSWIDTH-1:0] address; // this increments for each word
|
||||
reg [ADDRESSWIDTH-1:0] length;
|
||||
wire increment_address; // this increments the 'address' register when write is asserted and waitrequest is de-asserted
|
||||
wire read_fifo;
|
||||
wire user_buffer_empty;
|
||||
|
||||
|
||||
|
||||
// registering the control_fixed_location bit
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin
|
||||
if (reset == 1)
|
||||
begin
|
||||
control_fixed_location_d1 <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (control_go == 1)
|
||||
begin
|
||||
control_fixed_location_d1 <= control_fixed_location;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
// master word increment counter
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin
|
||||
if (reset == 1)
|
||||
begin
|
||||
address <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (control_go == 1)
|
||||
begin
|
||||
address <= control_write_base;
|
||||
end
|
||||
else if ((increment_address == 1) & (control_fixed_location_d1 == 0))
|
||||
begin
|
||||
address <= address + BYTEENABLEWIDTH; // always performing word size accesses
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// master length logic
|
||||
always @ (posedge clk or posedge reset)
|
||||
begin
|
||||
if (reset == 1)
|
||||
begin
|
||||
length <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (control_go == 1)
|
||||
begin
|
||||
length <= control_write_length;
|
||||
end
|
||||
else if (increment_address == 1)
|
||||
begin
|
||||
length <= length - BYTEENABLEWIDTH; // always performing word size accesses
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
// controlled signals going to the master/control ports
|
||||
assign master_address = address;
|
||||
assign master_byteenable = -1; // all ones, always performing word size accesses
|
||||
assign control_done = (length == 0);
|
||||
assign master_write = (user_buffer_empty == 0) & (control_done == 0);
|
||||
|
||||
assign increment_address = (user_buffer_empty == 0) & (master_waitrequest == 0) & (control_done == 0);
|
||||
assign read_fifo = increment_address;
|
||||
|
||||
// write data feed by user logic
|
||||
scfifo the_user_to_master_fifo (
|
||||
.aclr (reset),
|
||||
.clock (clk),
|
||||
.data (user_buffer_data),
|
||||
.full (user_buffer_full),
|
||||
.empty (user_buffer_empty),
|
||||
.q (master_writedata),
|
||||
.rdreq (read_fifo),
|
||||
.wrreq (user_write_buffer)
|
||||
);
|
||||
defparam the_user_to_master_fifo.lpm_width = DATAWIDTH;
|
||||
defparam the_user_to_master_fifo.lpm_numwords = FIFODEPTH;
|
||||
defparam the_user_to_master_fifo.lpm_showahead = "ON";
|
||||
defparam the_user_to_master_fifo.use_eab = (FIFOUSEMEMORY == 1)? "ON" : "OFF";
|
||||
defparam the_user_to_master_fifo.add_ram_output_register = "OFF";
|
||||
defparam the_user_to_master_fifo.underflow_checking = "OFF";
|
||||
defparam the_user_to_master_fifo.overflow_checking = "OFF";
|
||||
|
||||
endmodule
|
Loading…
x
Reference in New Issue
Block a user