OpenCores
URL https://opencores.org/ocsvn/open_free_list/open_free_list/trunk

Subversion Repositories open_free_list

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/open_free_list/trunk/hdl/open_free_list.v
0,0 → 1,314
module open_free_list #(parameter RAM_W = 128, RAM_E = 0, RAM_S = 64, CNK_S = 128, RAM_TYPE = "MRAM", FL_AEMPTY_LVL=2) (
input wire reset_n,
input wire clk,
// Write side
output wire [clog2((RAM_S*1024)/CNK_S)-1:0] fl_q,
output wire fl_aempty,
output wire fl_empty,
input wire wren,
input wire [RAM_W+RAM_E-1:0] din,
input wire eop,
// Read side
input wire [clog2((RAM_S*1024)/CNK_S)-1:0] chunk_num,
input wire load_req,
input wire rel_req,
output reg load_rel_ack,
input wire rden,
output wire [RAM_W+RAM_E-1:0] dout
);
 
localparam FL_S = (RAM_S*1024)/CNK_S;
localparam FL_W = clog2(FL_S);
localparam FL_ADDR_W = FL_W;
localparam LL_W = FL_W+1;
localparam RAM_ADDR_W = clog2((RAM_S*1024)/(RAM_W/8));
localparam LINES_IN_CNK = CNK_S/(RAM_W/8);
localparam IN_CNK_ADDR_W = clog2(LINES_IN_CNK);
 
 
wire [RAM_W+RAM_E-1:0] ram_q;
reg [RAM_ADDR_W-1:0] ram_rd_addr;
wire [RAM_ADDR_W-1:0] ram_wr_addr;
reg [RAM_ADDR_W-1:0] ram_wr_addr_lat;
reg wr_eop_while_ll;
reg [FL_W-1:0] fl_data;
wire [FL_ADDR_W-1:0] fl_lvl;
reg fl_rden;
reg fl_wren;
wire [FL_W:0] ll_data;
wire [FL_W:0] ll_q;
reg [FL_ADDR_W-1:0] ll_rd_addr;
wire [FL_ADDR_W-1:0] ll_wr_addr;
wire ll_wren;
wire ll_eop;
 
reg [FL_ADDR_W-1:0] fl_init_cnt;
reg fl_init;
reg fl_init_r1;
reg fl_init_r2;
reg fl_init_r3;
reg fl_init_wr;
 
reg int_sop;
reg rel_req_from_idle;
 
wire load_req_p;
wire [FL_ADDR_W-1:0] nxt_chunk_ptr;
 
reg [2:0] ns_rd_sm;
reg [2:0] cs_rd_sm;
parameter IDLE = 3'd0,
PREFETCH = 3'd1,
RD = 3'd2,
WAIT_REL = 3'd3,
REL_DELAY1 = 3'd4,
REL_DELAY2 = 3'd5,
REL_WR2FL = 3'd6;
 
reg sm_rel_ctrl;
reg sm_rel_wren;
 
reg rden_r1;
reg int_rden;
reg int_rden_r1;
reg load_req_r1;
reg [RAM_ADDR_W-1:0] usr_ram_rd_addr_r1;
 
altsyncram3 ram (
.data (din),
.rd_aclr (~reset_n),
.rdaddress (ram_rd_addr),
.rdclock (clk),
.rdclocken (int_rden | rden),
.wraddress (ram_wr_addr),
.wrclock (clk),
.wrclocken (1'b1),
.wren (wren),
.q (dout)
);
defparam
ram.A_WIDTH = RAM_W+RAM_E,
ram.A_WIDTHAD = RAM_ADDR_W,
ram.RAM_TYPE = RAM_TYPE,
ram.USE_RDEN = 0;
 
alt_scfifo free_list(
.aclr (~reset_n),
.clock (clk),
.data (fl_init_wr ? fl_init_cnt : fl_data),
.rdreq (fl_rden),
.sclr (1'b0),
.wrreq (fl_init_wr | fl_wren),
.almost_empty (fl_aempty),
.almost_full (),
.empty (fl_empty),
.full (),
.q (fl_q),
.usedw (fl_lvl)
);
defparam
free_list.FIFO_WIDTH = FL_W,
free_list.FIFO_DEPTH = FL_ADDR_W,
free_list.FIFO_TYPE = "M4K",
free_list.FIFO_SHOW = "ON",
free_list.FIFO_AEMPTY = FL_AEMPTY_LVL;
 
 
altsyncram3 link_list(
.data (ll_data),
.rd_aclr (~reset_n),
.rdaddress (sm_rel_ctrl ? nxt_chunk_ptr : ll_rd_addr),
.rdclock (clk),
.rdclocken (1'b1),
.wraddress (ll_wr_addr),
.wrclock (clk),
.wrclocken (1'b1),
.wren (ll_wren),
.q (ll_q)
);
defparam
link_list.A_WIDTH = LL_W,
link_list.A_WIDTHAD = FL_ADDR_W,
link_list.RAM_TYPE = "M4K",
link_list.USE_RDEN = 0;
 
 
// Free list init
 
always @ (posedge clk, negedge reset_n)
begin
if (reset_n==1'b0)
begin
fl_init_cnt <= {FL_ADDR_W{1'b0}};
fl_init <= 1'b0;
fl_init_r1 <= 1'b0;
fl_init_r2 <= 1'b0;
fl_init_r3 <= 1'b0;
fl_init_wr <= 1'b0;
end
else
begin
fl_init_cnt <= fl_init_wr ? fl_init_cnt + 1'b1 : {FL_ADDR_W{1'b0}};
fl_init <= 1'b1;
fl_init_r1 <= fl_init;
fl_init_r2 <= fl_init_r1;
fl_init_r3 <= fl_init_r2;
fl_init_wr <= !fl_init_r3 && fl_init_r2 ? 1'b1 : fl_init_cnt=={FL_ADDR_W{1'b1}} ? 1'b0 : fl_init_wr;
end
end
 
 
// Write side
 
assign ram_wr_addr = int_sop || (wren && ram_wr_addr_lat[IN_CNK_ADDR_W-1:0]==(LINES_IN_CNK-1)) ? {fl_q, {IN_CNK_ADDR_W{1'b0}}}
: wren ? ram_wr_addr_lat + 1'b1
: ram_wr_addr_lat;
assign ll_eop = wren && ram_wr_addr[IN_CNK_ADDR_W-1:0]==0 && eop ? 1'b0 : eop | wr_eop_while_ll;
assign ll_wr_addr = ram_wr_addr_lat[RAM_ADDR_W-1:IN_CNK_ADDR_W];
assign ll_data = {fl_q, ll_eop};
assign ll_wren = (wren && ((ram_wr_addr[IN_CNK_ADDR_W-1:0]==0) || eop)) || wr_eop_while_ll ? 1'b1 : 1'b0;
 
 
always @ (posedge clk, negedge reset_n)
begin
if (reset_n==1'b0)
begin
fl_rden <= 1'b0;
int_sop <= 1'b1;
ram_wr_addr_lat <= {RAM_ADDR_W{1'b0}};
wr_eop_while_ll <= 1'b0;
end
else
begin
fl_rden <= wren && (ram_wr_addr[IN_CNK_ADDR_W-1:0]==0) ? 1'b1 : 1'b0;
int_sop <= wren && eop ? 1'b1 :
wren ? 1'b0 :
int_sop;
ram_wr_addr_lat <= ram_wr_addr;
wr_eop_while_ll <= wren && ram_wr_addr[IN_CNK_ADDR_W-1:0]==0 && eop ? 1'b1 : 1'b0;
end
end
 
// Read side
assign load_req_p = ~load_req_r1 & load_req;
assign nxt_chunk_ptr = ll_q[FL_W:1]; //can be sampled
 
always @*
begin
case(cs_rd_sm)
IDLE:
ns_rd_sm = fl_init_wr ? IDLE :
rel_req ? REL_DELAY1 :
load_req ? PREFETCH :
IDLE;
PREFETCH:
ns_rd_sm = RD;
RD:
ns_rd_sm = load_req ? PREFETCH :
rden && (usr_ram_rd_addr_r1[IN_CNK_ADDR_W-1:0]==(LINES_IN_CNK-1)) && ll_q[0] ? WAIT_REL : // true if the current chunk is the last chunk and was reached to its end and is released now : REL_WR2FL // true if the current chunk was reached to its end and is released now and is the last one
rel_req ? REL_WR2FL :
RD;
WAIT_REL:
ns_rd_sm = rel_req ? IDLE : WAIT_REL;
REL_DELAY1:
ns_rd_sm = REL_DELAY2;
REL_DELAY2:
ns_rd_sm = REL_WR2FL;
REL_WR2FL:
ns_rd_sm = ll_q[0] ? IDLE : REL_DELAY2;
endcase
end
 
always @*
begin
rel_req_from_idle = 1'b0;
int_rden = 1'b0;
load_rel_ack = 1'b0;
sm_rel_ctrl = 1'b1;
sm_rel_wren = 1'b0;
case(cs_rd_sm)
IDLE:
begin
rel_req_from_idle = rel_req;
sm_rel_ctrl = rel_req;
end
PREFETCH:
begin
int_rden = 1'b1;
load_rel_ack = 1'b1;
sm_rel_ctrl = 1'b0;
end
RD:
begin
sm_rel_ctrl = 1'b0;
end
WAIT_REL:
begin
load_rel_ack = rel_req;
end
REL_DELAY1:
begin
end
REL_DELAY2:
begin
end
REL_WR2FL:
begin
sm_rel_wren = 1'b1;
load_rel_ack = ll_q[0];
end
endcase
end
 
always @ (posedge clk, negedge reset_n)
begin
if (reset_n==1'b0)
begin
cs_rd_sm <= 3'd0;
rden_r1 <= 1'b0;
int_rden_r1 <= 1'b0;
load_req_r1 <= 1'b0;
ll_rd_addr <= {FL_ADDR_W{1'b0}};
ram_rd_addr <= {RAM_ADDR_W{1'b0}};
usr_ram_rd_addr_r1 <= {RAM_ADDR_W{1'b0}};
fl_wren <= 1'b0;
fl_data <= {FL_W{1'b0}};
end
else
begin
cs_rd_sm <= ns_rd_sm;
rden_r1 <= rden;
int_rden_r1 <= int_rden;
load_req_r1 <= load_req;
 
ll_rd_addr <= load_req_p || rel_req_from_idle ? chunk_num :
sm_rel_wren || ((!sm_rel_ctrl && rden && (usr_ram_rd_addr_r1[IN_CNK_ADDR_W-1:0]==(LINES_IN_CNK-1)))) ? nxt_chunk_ptr :
ll_rd_addr;
ram_rd_addr <= load_req_p ? {chunk_num, {IN_CNK_ADDR_W{1'b0}}} :
rden && (ram_rd_addr[IN_CNK_ADDR_W-1:0]==(LINES_IN_CNK-1)) ? {nxt_chunk_ptr, {IN_CNK_ADDR_W{1'b0}}} :
rden || int_rden ? ram_rd_addr + 1'b1 :
ram_rd_addr;
usr_ram_rd_addr_r1 <= !sm_rel_ctrl && (rden || int_rden) ? ram_rd_addr : usr_ram_rd_addr_r1;
fl_wren <= (!sm_rel_ctrl && rden && (usr_ram_rd_addr_r1[IN_CNK_ADDR_W-1:0]==(LINES_IN_CNK-1))) || sm_rel_wren ? 1'b1 : 1'b0;
fl_data <= rel_req_from_idle ? chunk_num :
sm_rel_wren ? ll_rd_addr :
usr_ram_rd_addr_r1[RAM_ADDR_W-1:IN_CNK_ADDR_W];
 
end
end
 
/********************************************************
clog2 - function that returns log2 of a value rounded up
- min return value is 1 (in case of clog2(1)=1)
********************************************************/
function integer clog2(input integer value);
begin
value = value-1;
for (clog2=0; value>0; clog2=clog2+1)
value = value>>1;
if (clog2 == 0)
clog2 = 1;
end
endfunction
 
endmodule
/open_free_list/trunk/docs/open_free_list.html
0,0 → 1,246
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1255">
<title>Open FreeList Readme</title>
</head>
<body>
<h1>General Description</h1>
<p>
The Open FreeList module is used to manage a set of variable sized packets inside a fixed memory block.
The memory block is partitioned into fixed sized chunks and each packet uses one or more chunks.
The module offers three possible actions:
<ol>
<li>Write a packet into memory</li>
<li>Read a packet from memory</li>
<li>Release a packet</li>
</ol>
</p>
<h1>Using the Module</h1>
<h2>Parameters</h2>
<table border="1">
<col align="left"/>
<col align="left"/>
<col align="center"/>
<col align="center"/>
<tr>
<th>Name</th>
<th>Description</th>
<th>Unit</th>
<th>Default Value</th>
</tr>
<tr>
<td>RAM_W</td>
<td>Memory block width</td>
<td>bits</td>
<td>128</td>
</tr>
<tr>
<td>RAM_E</td>
<td>Memory block extra data</td>
<td>bits</td>
<td>0</td>
</tr>
<tr>
<td>RAM_S</td>
<td>Memory block size</td>
<td>KBytes</td>
<td>64</td>
</tr>
<tr>
<td>CHK_S</td>
<td>Chunk size</td>
<td>Bytes</td>
<td>128</td>
</tr>
<tr>
<td>RAM_TYPE</td>
<td>Memory block type</td>
<td>string</td>
<td>"MRAM"</td>
</tr>
<tr>
<td>FL_AEMPTY_LVL</td>
<td>FreeList almost empty level</td>
<td>#</td>
<td>2</td>
</tr>
</table>
<h2>Interface</h2>
<table border="1">
<col align="left"/>
<col align="center"/>
<col align="center"/>
<col align="left"/>
<tr>
<th>Name</th>
<th>Direction</th>
<th>Width</th>
<th>Description</th>
</tr>
<tr>
<td colspan="4" align="center"><b>global signals</b></td>
</tr>
<tr>
<td>reset_n</td>
<td>input</td>
<td>1</td>
<td>async reset (active low)</td>
</tr>
<tr>
<td>clk</td>
<td>input</td>
<td>1</td>
<td>clock</td>
</tr>
<tr>
<td colspan="4" align="center"><b>write interface</b></td>
</tr>
<tr>
<td>fl_q</td>
<td>output</td>
<td>clog(#_of_chunks)</td>
<td>first chunk number for a new packet.<br />capture this value and use it to read/release the packet</td>
</tr>
<tr>
<td>fl_aempty</td>
<td>output</td>
<td>1</td>
<td>indicates that the number of chunks reached the almost empty level</td>
</tr>
<tr>
<td>fl_empty</td>
<td>output</td>
<td>1</td>
<td>no more chunks available. do not write any more</td>
</tr>
<tr>
<td>wren</td>
<td>input</td>
<td>1</td>
<td>write pulse. writes the data on din into the memory block</td>
</tr>
<tr>
<td>din</td>
<td>input</td>
<td>RAM_W+RAM_E</td>
<td>data to write into memory block</td>
</tr>
<tr>
<td>eop</td>
<td>input</td>
<td>1</td>
<td>end-of-packet indication. assert on last write of packet</td>
</tr>
<tr>
<td colspan="4" align="center"><b>read interface</b></td>
</tr>
<tr>
<td>chunk_num</td>
<td>input</td>
<td>clog(#_of_chunks)</td>
<td>first chunk in a packet to be read or released</td>
</tr>
<tr>
<td>load_req</td>
<td>input</td>
<td>1</td>
<td>request to read a packet starting at chunk number 'chunk_num'</td>
</tr>
<tr>
<td>rel_req</td>
<td>input</td>
<td>1</td>
<td>request to release a packet starting at chunk number 'chunk_num'.<br />also required after a packet is read</td>
</tr>
<tr>
<td>load_rel_ack</td>
<td>output</td>
<td>1</td>
<td>acknowledge a read or release request</td>
</tr>
<tr>
<td>rden</td>
<td>input</td>
<td>1</td>
<td>read request. data on 'dout' is valid one clock later</td>
</tr>
<tr>
<td>dout</td>
<td>output</td>
<td>RAM_W+RAM_E</td>
<td>data read from memory block</td>
</tr>
</table>
<h2>Operations</h2>
<h3>Write</h3>
<p>
To write a packet, do the following:
<ul>
<li>make sure 'fl_empty' is de-asserted</li>
<li>capture the value on 'fl_q'. it will be used later to reference this packet</li>
<li>while 'fl_empty' is not asserted do:</li>
<ul>
<li>write the next data line in 'din'</li>
<li>assert 'wren'</li>
<li>on the last line of the packet, assert 'eop' as well</li>
</ul>
</ul>
</p>
<h3>Read</h3>
<p>
To read a packet that was previously written, do the following:
<ul>
<li>set 'chunk_num' to the value of the first chunk in the packet.<br />
this value was obtained from 'fl_q' when the packet was written</li>
<li>assert 'load_req'</li>
<li>when 'load_rel_ack' is asserted, for each line of data do:</li>
<ul>
<li>assert 'rden'</li>
<li>capture 'dout' one cycle later</li>
</ul>
</ul>
To determine the last line of data, you could:
<ul>
<li>store the packet length in an external structure</li>
<li>use the extra bits in the memory block to hold an indication such as end-of-packet</li>
</ul>
</p>
<p>
Note that the 'eop' indication that is written in the write operation is not available on a read operation.
</p>
<p>
<i>Important:</i> after a read is complete, a release operation must be explicitly performed.
There is no need to set the 'chunk_num' value after a read operation.
The chunks are released when the packet is read, but the last chunk requires an explicit release operation.
</p>
<h3>Release</h3>
<p>A packet can be released under two circumstances:
<ol>
<li>when a read is complete, a release must be issued</li>
<li>if a packet is not needed, it can be released without reading it</li>
</ol>
To release a packet, do the following:
<ul>
<li>set 'chunk_num' to the first chunk of the packet (not required after a read)</li>
<li>assert 'rel_req'</li>
<li>when 'load_rel_ack' is asserted, you are done</li>
</ul>
</p>
<h2>Memories</h2>
<p>
Three memories are used in this module:
<ol>
<li>ram - dual port memory. two cycles to read</li>
<li>free_list - single clock lookahead FIFO</li>
<li>link_list - dual port memory. two cycles to read</li>
</ol>
The target architecture is Altera Sratix. There should be matching memory blocks in other architectures.
</p>
<p><br /><br /></p>
<p>
Code: Alex Manash - Crescendo Networks<br />
Docs: Amit Fridman - Crescendo Networks
</p>
</body>
</html>
/open_free_list/trunk/sim/vlog.list
0,0 → 1,4
../hdl/open_free_list.v
tb_open_free_list.v
altsyncram3.v
alt_scfifo.v
/open_free_list/trunk/sim/altsyncram3.v
0,0 → 1,108
/*******************************************************************************
 
MODULE NAME: altsyncram3
 
DESCRIPTION
This module is a parametrized dual port ram with a registered output port
It is optional to define it's input address and output address and it's
depth.
 
REVISION HISTORY
05FEB03 First Created -ac-
*******************************************************************************/
module altsyncram3
(
data,
byteena,
rd_aclr,
rdaddress,
rdclock,
rdclocken,
rden,
wraddress,
wrclock,
wrclocken,
wren,
q);
 
parameter A_WIDTH = 288;
parameter A_WIDTHAD = 9;
parameter B_WIDTH = A_WIDTH;
parameter B_WIDTHAD = A_WIDTHAD;
parameter A_NUMWORDS = 1<<A_WIDTHAD;
parameter B_NUMWORDS = 1<<B_WIDTHAD;
parameter RAM_TYPE = "AUTO";
parameter BYTE_ENA = 1;
parameter USE_RDEN = 1;
 
parameter TYPE = RAM_TYPE == "M4K" | RAM_TYPE == "M9K"? "M9K":
RAM_TYPE == "M512" | RAM_TYPE == "MLAB"? "MLAB":
RAM_TYPE == "M-RAM" | RAM_TYPE == "M144K"? "M144K":
"AUTO";
 
parameter REG_B = "CLOCK1";
 
input [A_WIDTH-1:0] data;
input [BYTE_ENA-1 :0] byteena;
input rd_aclr;
input [B_WIDTHAD-1:0] rdaddress;
input rdclock;
input rdclocken;
input rden;
input [A_WIDTHAD-1:0] wraddress;
input wrclock;
input wrclocken;
input wren;
output [B_WIDTH-1:0] q;
 
wire [B_WIDTH-1:0] sub_wire0;
wire [B_WIDTH-1:0] q = sub_wire0[B_WIDTH-1:0];
wire [BYTE_ENA-1 :0] byteena_wire = BYTE_ENA==1 ? 1'b1 : byteena;
wire rden_wire = USE_RDEN ? rden : 1'b1;
 
altsyncram altsyncram_component (
.clocken0(wrclocken),
.clocken1(rdclocken),
.wren_a(wren),
.clock0(wrclock),
.aclr1 (rd_aclr),
.clock1(rdclock),
.address_a(wraddress),
.address_b(rdaddress),
.rden_b(rden_wire),
.data_a(data),
.q_b(sub_wire0),
.aclr0 (1'b0),
.addressstall_a (1'b0),
.addressstall_b (1'b0),
.byteena_a (byteena_wire),
.byteena_b (1'b1),
.clocken2 (1'b1),
.clocken3 (1'b1),
.data_b ({B_WIDTH{1'b1}}),
.eccstatus (),
.q_a (),
.rden_a (1'b1),
.wren_b (1'b0));
defparam
altsyncram_component.address_aclr_b = "CLEAR1",
altsyncram_component.address_reg_b = "CLOCK1",
altsyncram_component.clock_enable_input_a = "NORMAL",
altsyncram_component.clock_enable_input_b = "NORMAL",
altsyncram_component.clock_enable_output_b = "NORMAL",
altsyncram_component.intended_device_family = "Stratix III",
altsyncram_component.lpm_type = "altsyncram",
altsyncram_component.numwords_a = A_NUMWORDS,
altsyncram_component.numwords_b = B_NUMWORDS,
altsyncram_component.operation_mode = "DUAL_PORT",
altsyncram_component.outdata_aclr_b = "CLEAR1",
altsyncram_component.outdata_reg_b = REG_B,
altsyncram_component.power_up_uninitialized = "FALSE",
altsyncram_component.ram_block_type = TYPE,
altsyncram_component.rdcontrol_reg_b = "CLOCK1",
altsyncram_component.widthad_a = A_WIDTHAD,
altsyncram_component.widthad_b = B_WIDTHAD,
altsyncram_component.width_a = A_WIDTH,
altsyncram_component.width_b = B_WIDTH,
altsyncram_component.width_byteena_a = BYTE_ENA;
endmodule // altsyncram3
/open_free_list/trunk/sim/tb_open_free_list.v
0,0 → 1,186
`timescale 1ns/1ps
 
module tb_open_free_list;
 
reg reset_n;
reg clk;
wire [8:0] fl_q;
wire fl_aempty;
wire fl_empty;
reg wren;
reg [71:0] din;
reg eop;
reg [8:0] chunk_num;
reg load_req;
reg rel_req;
wire load_rel_ack;
reg rden;
wire [71:0] dout;
 
reg [8:0] pkt1_chunk;
reg [8:0] pkt2_chunk;
reg [8:0] pkt3_chunk;
 
open_free_list open_free_list(
.reset_n(reset_n),
.clk(clk),
.fl_q(fl_q),
.fl_aempty(fl_aempty),
.fl_empty(fl_empty),
.wren(wren),
.din(din),
.eop(eop),
.chunk_num(chunk_num),
.load_req(load_req),
.rel_req(rel_req),
.load_rel_ack(load_rel_ack),
.rden(rden),
.dout(dout)
);
defparam
open_free_list.RAM_W = 64,
open_free_list.RAM_E = 8;
 
initial // reset
begin
reset_n <= 1'b0;
#1000 reset_n <= 1'b1;
end
 
initial // clock
clk <= 1'b0;
always
#5 clk <= ~clk;
 
initial // init all signals
begin
wren <= 1'b0;
din <= 72'b0;
eop <= 1'b0;
chunk_num <= 9'b0;
load_req <= 1'b0;
rel_req <= 1'b0;
rden <= 1'b0;
end
 
initial // test
begin
#2000;
@(posedge clk);
// write a short packet
pkt1_chunk <= fl_q;
din <= 72'h000001020304050607;
wren <= 1'b1;
@(posedge clk);
din <= 72'h0108090a0b0c0d0e0f;
eop <= 1'b1;
@(posedge clk);
wren <= 1'b0;
eop <= 1'b0;
#1000;
@(posedge clk);
 
// write a longer packet
pkt2_chunk <= fl_q;
din <= 72'h800001020304050607;
wren <= 1'b1;
@(posedge clk);
din <= 72'h8008090a0b0c0d0e0f;
@(posedge clk);
din <= 72'h801011121314151617;
@(posedge clk);
din <= 72'h8018191a1b1c1d1e1f;
@(posedge clk);
din <= 72'h802021222324252627;
@(posedge clk);
din <= 72'h8028292a2b2c2d2e2f;
@(posedge clk);
din <= 72'h803031323334353637;
@(posedge clk);
din <= 72'h8038393a3b3c3d3e3f;
@(posedge clk);
din <= 72'h804041424344454647;
@(posedge clk);
din <= 72'h8048494a4b4c4d4e4f;
@(posedge clk);
din <= 72'h805051525354555657;
@(posedge clk);
din <= 72'h8058595a5b5c5d5e5f;
@(posedge clk);
din <= 72'h806061626364656667;
@(posedge clk);
din <= 72'h8068696a6b6c6d6e6f;
@(posedge clk);
din <= 72'h807071727374757677;
@(posedge clk);
din <= 72'h8078797a7b7c7d7e7f;
@(posedge clk);
din <= 72'h818081828384858687;
eop <= 1'b1;
@(posedge clk);
wren <= 1'b0;
eop <= 1'b0;
#1000;
@(posedge clk);
// read the first packet
chunk_num <= pkt1_chunk;
load_req <= 1'b1;
@(posedge load_rel_ack);
load_req <= 1'b0;
@(posedge clk);
rden <= 1'b1;
@(posedge clk);
@(posedge clk);
rden <= 1'b0;
rel_req <= 1'b1;
@(posedge load_rel_ack);
rel_req <= 1'b0;
#1000;
@(posedge clk);
// write a 3rd packet (short)
pkt3_chunk <= fl_q;
din <= 72'hc00001020304050607;
wren <= 1'b1;
@(posedge clk);
din <= 72'hc108090a0b0c0d0e0f;
eop <= 1'b1;
@(posedge clk);
wren <= 1'b0;
eop <= 1'b0;
#1000;
@(posedge clk);
// release the third packet without reading
chunk_num <= pkt3_chunk;
rel_req <= 1'b1;
@(posedge load_rel_ack);
rel_req <= 1'b0;
#1000;
@(posedge clk);
 
// read a few lines of packet 2 and then release it
chunk_num <= pkt2_chunk;
load_req <= 1'b1;
@(posedge load_rel_ack);
load_req <= 1'b0;
@(posedge clk);
rden <= 1'b1;
@(posedge clk);
@(posedge clk);
@(posedge clk);
@(posedge clk);
rden <= 1'b0;
rel_req <= 1'b1;
@(posedge load_rel_ack);
rel_req <= 1'b0;
end
 
endmodule // tb_open_free_list
/open_free_list/trunk/sim/vsim.list
0,0 → 1,6
-L /mnt/nfs/work/quartus_81/altera_mf
-L /mnt/nfs/work/quartus_81/220model
-L /mnt/nfs/work/quartus_81/stratixiii_atoms
-L /mnt/nfs/work/quartus_81/sgate
 
work.tb_open_free_list
/open_free_list/trunk/sim/alt_scfifo.v
0,0 → 1,134
// megafunction wizard: %FIFO%
// GENERATION: STANDARD
// VERSION: WM1.0
// MODULE: scfifo
 
// ============================================================
// File Name: sc_fifo.v
// Megafunction Name(s):
// scfifo
//
// Simulation Library Files(s):
// altera_mf
// ============================================================
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 7.2 Build 175 11/20/2007 SP 1 SJ Full Version
// ************************************************************
 
 
//Copyright (C) 1991-2007 Altera Corporation
//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 from 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, Altera MegaCore Function License
//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.
 
module alt_scfifo (
aclr,
clock,
data,
rdreq,
sclr,
wrreq,
almost_empty,
almost_full,
empty,
full,
q,
usedw,
fifo_ovf,
fifo_unf
);
 
parameter FIFO_WIDTH = 144;
parameter FIFO_DEPTH = 7;
parameter FIFO_TYPE = "AUTO";
parameter FIFO_SHOW = "OFF";
parameter USE_EAB = "ON";
 
parameter FIFO_NUMWORDS = 1 << FIFO_DEPTH;
parameter FIFO_AEMPTY = 0;
parameter FIFO_AFULL = FIFO_NUMWORDS;
parameter FIFO_UNF = "TRUE";
 
parameter TYPE = FIFO_TYPE == "M4K" | FIFO_TYPE == "M9K" ? "RAM_BLOCK_TYPE=M9K":
FIFO_TYPE == "M512" | FIFO_TYPE == "MLAB" ? "RAM_BLOCK_TYPE=MLAB":
FIFO_TYPE == "M-RAM" | FIFO_TYPE == "M144K"? "RAM_BLOCK_TYPE=M144K":
"RAM_BLOCK_TYPE=AUTO";
 
input aclr;
input clock;
input [FIFO_WIDTH-1:0] data;
input rdreq;
input sclr;
input wrreq;
output almost_empty;
output almost_full;
output empty;
output full;
output [FIFO_WIDTH-1:0] q;
output [FIFO_DEPTH-1:0] usedw;
output fifo_ovf;
output fifo_unf;
 
reg fifo_ovf;
reg fifo_unf;
 
always @ (posedge clock or posedge aclr)
if (aclr) begin
fifo_ovf <= 1'b0;
fifo_unf <= 1'b0;
end
else begin
// synthesis translate_off
if (fifo_ovf) begin
$display ("%m: ERROR!!! %m alt_scfifo FIFO overflow, simulation stop");
$stop;
end
if (fifo_unf & (FIFO_UNF == "TRUE")) begin
$display ("%m: ERROR!!! alt_dcfifo FIFO underflow, simulation stop");
$stop;
end
// synthesis translate_on
fifo_ovf <= (full & wrreq) | fifo_ovf;
fifo_unf <= ((empty & rdreq) | fifo_unf) & (FIFO_UNF == "TRUE");
end
 
scfifo scfifo_component (
.rdreq (rdreq),
.sclr (sclr),
.aclr (aclr),
.clock (clock),
.wrreq (wrreq),
.data (data),
.almost_full (almost_full),
.usedw (usedw),
.empty (empty),
.almost_empty(almost_empty),
.q (q),
.full (full)
);
defparam
scfifo_component.add_ram_output_register = "ON",
scfifo_component.almost_empty_value = FIFO_AEMPTY,
scfifo_component.almost_full_value = FIFO_AFULL,
scfifo_component.intended_device_family = "Stratix III",
scfifo_component.lpm_hint = TYPE,
scfifo_component.lpm_numwords = FIFO_NUMWORDS,
scfifo_component.lpm_showahead = FIFO_SHOW,
scfifo_component.lpm_type = "scfifo",
scfifo_component.lpm_width = FIFO_WIDTH,
scfifo_component.lpm_widthu = FIFO_DEPTH,
scfifo_component.overflow_checking = "ON",
scfifo_component.underflow_checking = "ON",
scfifo_component.use_eab = USE_EAB;
endmodule // alt_scfifo

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.