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

Subversion Repositories apb_mstr

Compare Revisions

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

Rev 1 → Rev 2

/trunk/run/run.bat
0,0 → 1,6
 
echo off
 
..\..\..\robust.exe ../src/base/apb_master.v -od out -I ../src/gen -list list.txt -listpath -header
 
echo Completed RobustVerilog APB master run - results in run/out/
/trunk/run/run.sh
0,0 → 1,5
#!/bin/bash
 
../../../robust ../src/base/apb_master.v -od out -I ../src/gen -list list.txt -listpath -header
 
echo Completed RobustVerilog APB master run - results in run/out/
/trunk/src/gen/prgen_fifo.v
0,0 → 1,196
/////////////////////////////////////////////////////////////////////
//// ////
//// Author: Eyal Hochberg ////
//// eyal@provartec.com ////
//// ////
//// Downloaded from: http://www.opencores.org ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2010 Provartec LTD ////
//// www.provartec.com ////
//// info@provartec.com ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation.////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more////
//// details. http://www.gnu.org/licenses/lgpl.html ////
//// ////
/////////////////////////////////////////////////////////////////////
 
IFDEF STUB
OUTFILE prgen_fifo_stub.v
module prgen_fifo_stub(PORTS);
ELSE STUB
OUTFILE prgen_fifo.v
module prgen_fifo(PORTS);
ENDIF STUB
parameter WIDTH = 8;
parameter DEPTH_FULL = 8;
 
parameter SINGLE = DEPTH_FULL == 1;
parameter DEPTH = SINGLE ? 1 : DEPTH_FULL -1;
parameter DEPTH_BITS =
(DEPTH <= 2) ? 1 :
(DEPTH <= 4) ? 2 :
(DEPTH <= 8) ? 3 :
(DEPTH <= 16) ? 4 :
(DEPTH <= 32) ? 5 :
(DEPTH <= 64) ? 6 :
(DEPTH <= 128) ? 7 :
(DEPTH <= 256) ? 8 :
(DEPTH <= 512) ? 9 : 0; //0 is ilegal
 
parameter LAST_LINE = DEPTH-1;
 
input clk;
input reset;
 
input push;
input pop;
input [WIDTH-1:0] din;
output [WIDTH-1:0] dout;
IF STUB output [DEPTH_BITS:0] fullness;
output empty;
output full;
 
wire reg_push;
wire reg_pop;
wire fifo_push;
wire fifo_pop;
reg [DEPTH-1:0] full_mask_in;
reg [DEPTH-1:0] full_mask_out;
reg [DEPTH-1:0] full_mask;
reg [WIDTH-1:0] fifo [DEPTH-1:0];
wire fifo_empty;
wire next;
reg [WIDTH-1:0] dout;
reg dout_empty;
reg [DEPTH_BITS-1:0] ptr_in;
reg [DEPTH_BITS-1:0] ptr_out;
 
 
assign reg_push = push & fifo_empty & (dout_empty | pop);
assign reg_pop = pop & fifo_empty;
assign fifo_push = !SINGLE & push & (~reg_push);
assign fifo_pop = !SINGLE & pop & (~reg_pop);
always @(posedge clk or posedge reset)
if (reset)
begin
dout <= #FFD {WIDTH{1'b0}};
dout_empty <= #FFD 1'b1;
end
else if (reg_push)
begin
dout <= #FFD din;
dout_empty <= #FFD 1'b0;
end
else if (reg_pop)
begin
dout <= #FFD {WIDTH{1'b0}};
dout_empty <= #FFD 1'b1;
end
else if (fifo_pop)
begin
dout <= #FFD fifo[ptr_out];
dout_empty <= #FFD 1'b0;
end
always @(posedge clk or posedge reset)
if (reset)
ptr_in <= #FFD {DEPTH_BITS{1'b0}};
else if (fifo_push)
ptr_in <= #FFD ptr_in == LAST_LINE ? 0 : ptr_in + 1'b1;
 
always @(posedge clk or posedge reset)
if (reset)
ptr_out <= #FFD {DEPTH_BITS{1'b0}};
else if (fifo_pop)
ptr_out <= #FFD ptr_out == LAST_LINE ? 0 : ptr_out + 1'b1;
 
always @(posedge clk)
if (fifo_push)
fifo[ptr_in] <= #FFD din;
 
always @(/*AUTOSENSE*/fifo_push or ptr_in)
begin
full_mask_in = {DEPTH{1'b0}};
full_mask_in[ptr_in] = fifo_push;
end
always @(/*AUTOSENSE*/fifo_pop or ptr_out)
begin
full_mask_out = {DEPTH{1'b0}};
full_mask_out[ptr_out] = fifo_pop;
end
always @(posedge clk or posedge reset)
if (reset)
full_mask <= #FFD {DEPTH{1'b0}};
else if (fifo_push | fifo_pop)
full_mask <= #FFD (full_mask & (~full_mask_out)) | full_mask_in;
 
 
assign next = |full_mask;
assign fifo_empty = ~next;
assign empty = fifo_empty & dout_empty;
assign full = SINGLE ? !dout_empty : &full_mask;
 
 
IFDEF STUB
reg [DEPTH_BITS:0] fullness;
always @(posedge clk or posedge reset)
if (reset)
fullness <= #FFD {DEPTH_BITS+1{1'b0}};
else if (push | pop)
fullness <= #FFD fullness + push - pop;
wire overflow = full & fifo_push & (~fifo_pop);
wire underflow = empty & fifo_pop & (~fifo_push);
always @(posedge overflow)
begin
#1;
if (overflow)
begin
$display("-E-%m - overflow.\tTime: %0d ns", $time);
#1000;
$finish;
end
end
always @(posedge underflow)
begin
#1;
if (underflow)
begin
$display("-E-%m - underflow.\tTime: %0d ns", $time);
#1000;
$finish;
end
end
ENDIF STUB
endmodule
 
 
/trunk/src/gen/prgen_rand.v
0,0 → 1,87
/////////////////////////////////////////////////////////////////////
//// ////
//// Author: Eyal Hochberg ////
//// eyal@provartec.com ////
//// ////
//// Downloaded from: http://www.opencores.org ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2010 Provartec LTD ////
//// www.provartec.com ////
//// info@provartec.com ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation.////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more////
//// details. http://www.gnu.org/licenses/lgpl.html ////
//// ////
/////////////////////////////////////////////////////////////////////
 
function integer rand_chance;
input [31:0] chance_true;
 
begin
if (chance_true > 100)
begin
$display("RAND_CHANCE-E-: fatal error, rand_chance called with percent chance larger than 100.\tTime: %0d ns", $time);
$finish;
end
rand_chance = (rand(1,100) <= chance_true);
end
endfunction // rand_chance
 
 
function integer rand;
input [31:0] min;
input [31:0] max;
 
integer range;
begin
if (min > max)
begin
$display("RAND-E-: fatal error, rand was called with min larger than max.\tTime: %0d ns", $time);
$finish;
end
 
range = (max - min) + 1;
if (range == 0) range = -1;
rand = min + ($random % range);
end
endfunction // rand
 
 
function integer align;
input [31:0] num;
input [31:0] align_size;
integer align;
begin
align = num - (num % align_size);
end
endfunction
 
 
function integer rand_align;
input [31:0] min;
input [31:0] max;
input [31:0] align;
 
integer rand_align;
begin
rand_align = rand(min, max);
if (rand_align > align)
rand_align = align(rand_align, align);
end
endfunction
 
/trunk/src/base/axi2apb_rd.v
0,0 → 1,76
<##//////////////////////////////////////////////////////////////////
//// ////
//// Author: Eyal Hochberg ////
//// eyal@provartec.com ////
//// ////
//// Downloaded from: http://www.opencores.org ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2010 Provartec LTD ////
//// www.provartec.com ////
//// info@provartec.com ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation.////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more////
//// details. http://www.gnu.org/licenses/lgpl.html ////
//// ////
//////////////////////////////////////////////////////////////////##>
 
INCLUDE def_axi2apb.txt
OUTFILE PREFIX_axi2apb_rd.v
 
module PREFIX_axi2apb_rd (PORTS);
 
input clk;
input reset;
 
input GROUP_APB3;
input cmd_err;
input [ID_BITS-1:0] cmd_id;
output finish_rd;
port RGROUP_APB_AXI_R;
parameter RESP_OK = 2'b00;
parameter RESP_SLVERR = 2'b10;
parameter RESP_DECERR = 2'b11;
reg RGROUP_APB_AXI_R.OUT;
assign finish_rd = RVALID & RREADY & RLAST;
always @(posedge clk or posedge reset)
if (reset)
begin
RGROUP_APB_AXI_R.OUT <= #FFD {GROUP_APB_AXI_R.OUT.WIDTH{1'b0}};
end
else if (finish_rd)
begin
RGROUP_APB_AXI_R.OUT <= #FFD {GROUP_APB_AXI_R.OUT.WIDTH{1'b0}};
end
else if (psel & penable & (~pwrite) & pready)
begin
RID <= #FFD cmd_id;
RDATA <= #FFD prdata;
RRESP <= #FFD cmd_err ? RESP_SLVERR : pslverr ? RESP_DECERR : RESP_OK;
RLAST <= #FFD 1'b1;
RVALID <= #FFD 1'b1;
end
endmodule
 
/trunk/src/base/def_apb_master_static.txt
0,0 → 1,46
<##//////////////////////////////////////////////////////////////////
//// ////
//// Author: Eyal Hochberg ////
//// eyal@provartec.com ////
//// ////
//// Downloaded from: http://www.opencores.org ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2010 Provartec LTD ////
//// www.provartec.com ////
//// info@provartec.com ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation.////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more////
//// details. http://www.gnu.org/licenses/lgpl.html ////
//// ////
//////////////////////////////////////////////////////////////////##>
 
INCLUDE def_axi_master.txt
 
SWAP.GLOBAL DATA_BITS 32 ##AXI and APB data bits
SWAP.GLOBAL ID_NUM 1 ##Number of IDs (internal masters)
SWAP.GLOBAL ID0_VAL ID_BITS'b0000 ##AXI ID0
 
GROUP STUB_AXI_A overrides {
ID ID_BITS output
ADDR ADDR_BITS output
LEN LEN_BITS output
SIZE SIZE_BITS output
VALID 1 output
READY 1 input
}
 
/trunk/src/base/apb_master.v
0,0 → 1,172
/////////////////////////////////////////////////////////////////////
//// ////
//// Author: Eyal Hochberg ////
//// eyal@provartec.com ////
//// ////
//// Downloaded from: http://www.opencores.org ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2010 Provartec LTD ////
//// www.provartec.com ////
//// info@provartec.com ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation.////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more////
//// details. http://www.gnu.org/licenses/lgpl.html ////
//// ////
/////////////////////////////////////////////////////////////////////
 
//////////////////////////////////////
//
// General:
// The APB master is built of an AXI master and an AXI2APB bridge.
// The stub support APB (Amba2) and APB3 (Amba3) protocols,
// the define APB3 determines this (in def_apb_master.txt)
//
//
// Tasks:
//
// write_single(input addr, input wdata)
// Description: write a single APB burst
// Parameters:
// addr - address
// wdata - write data
//
// read_single(input master_num, input addr, output rdata)
// Description: read a single AB burst
// Parameters:
// addr - address
// rdata - return read data
//
// check_single(input master_num, input addr, input expected)
// Description: read a single AB burst and give an error if the data read does not match expected
// Parameters:
// addr - address
// expected - expected read data
//
// write_and_check_single(input master_num, input addr, input data)
// Description: write a single AB burst read it back and give an error if the write and read data don't match
// Parameters:
// addr - address
// data - data to write and expect on read
//
//
//////////////////////////////////////
 
 
OUTFILE apb_master.v
 
INCLUDE def_apb_master.txt
 
VERIFY (DATA_BITS==32) else only 32 bit data supported
module apb_master(PORTS);
 
input clk;
input reset;
output psel;
output penable;
output [ADDR_BITS-1:0] paddr;
output pwrite;
output [DATA_BITS-1:0] pwdata;
input [DATA_BITS-1:0] prdata;
IFDEF APB3
input pslverr;
input pready;
ELSE APB3
 
wire pslverr = 1'b0;
wire pready = 1'b1;
ENDIF APB3
 
wire GROUP_STUB_AXI;
 
//set random tasks to be only 32 bit singles
initial
begin
#1;
apb_master_axi_master.enable_all;
apb_master_axi_master.use_addr_base=1;
apb_master_axi_master.len_min=0;
apb_master_axi_master.len_max=0;
apb_master_axi_master.size_min=2;
apb_master_axi_master.size_max=2;
end
CREATE axi_master.v DEFCMD(SWAP.GLOBAL CONST(PREFIX) apb_master_axi_master)
apb_master_axi_master apb_master_axi_master(
.clk(clk),
.reset(reset),
.GROUP_STUB_AXI(GROUP_STUB_AXI),
.idle()
);
 
CREATE axi2apb.v DEFCMD(SWAP CONST(SLAVE_NUM) 1) DEFCMD(SWAP.GLOBAL CONST(PREFIX) apb_master)
 
apb_master_axi2apb apb_master_axi2apb(
.clk(clk),
.reset(reset),
.GROUP_STUB_AXI(GROUP_STUB_AXI),
 
.penable(penable),
.pwrite(pwrite),
.paddr(paddr),
.pwdata(pwdata),
.psel(psel),
.prdata(prdata),
.pready(pready),
.pslverr(pslverr)
);
task write_single;
input [ADDR_BITS-1:0] addr;
input [DATA_BITS-1:0] wdata;
begin
apb_master_axi_master.write_single(0, addr, wdata);
end
endtask
 
task read_single;
input [ADDR_BITS-1:0] addr;
output [DATA_BITS-1:0] rdata;
begin
apb_master_axi_master.read_single(0, addr, rdata);
end
endtask
 
task check_single;
input [ADDR_BITS-1:0] addr;
input [DATA_BITS-1:0] expected;
begin
apb_master_axi_master.check_single(0, addr, expected);
end
endtask
 
task write_and_check_single;
input [ADDR_BITS-1:0] addr;
input [DATA_BITS-1:0] data;
begin
apb_master_axi_master.write_and_check_single(0, addr, data);
end
endtask
 
endmodule
/trunk/src/base/def_axi2apb.txt
0,0 → 1,51
<##//////////////////////////////////////////////////////////////////
//// ////
//// Author: Eyal Hochberg ////
//// eyal@provartec.com ////
//// ////
//// Downloaded from: http://www.opencores.org ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2010 Provartec LTD ////
//// www.provartec.com ////
//// info@provartec.com ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation.////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more////
//// details. http://www.gnu.org/licenses/lgpl.html ////
//// ////
//////////////////////////////////////////////////////////////////##>
 
INCLUDE def_axi2apb_static.txt
 
SWAP #FFD #1 ## flip-flop delay
 
SWAP PREFIX soc ## prefix for all modules and file names
 
SWAP SLAVE_NUM 8 ## number of APB slaves
 
SWAP CMD_DEPTH 2 ## number of AXI command FIFO
 
SWAP ADDR_BITS 24 ## AXI and APB address bits
SWAP ID_BITS 4 ## AXI ID bits
SWAP DEC_BITS 8 ## Address MSBits for slave decoding
 
SWAP DEC_ADDR0 DEC_BITS'h00 ## Slave 0 address deciding
SWAP DEC_ADDR1 DEC_BITS'h01 ## Slave 1 address deciding
SWAP DEC_ADDR2 DEC_BITS'h02 ## Slave 2 address deciding
SWAP DEC_ADDR3 DEC_BITS'h03 ## Slave 3 address deciding
SWAP DEC_ADDR4 DEC_BITS'h10 ## Slave 4 address deciding
SWAP DEC_ADDR5 DEC_BITS'h11 ## Slave 5 address deciding
SWAP DEC_ADDR6 DEC_BITS'h12 ## Slave 6 address deciding
SWAP DEC_ADDR7 DEC_BITS'h13 ## Slave 7 address deciding
/trunk/src/base/axi2apb_mux.v
0,0 → 1,123
<##//////////////////////////////////////////////////////////////////
//// ////
//// Author: Eyal Hochberg ////
//// eyal@provartec.com ////
//// ////
//// Downloaded from: http://www.opencores.org ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2010 Provartec LTD ////
//// www.provartec.com ////
//// info@provartec.com ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation.////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more////
//// details. http://www.gnu.org/licenses/lgpl.html ////
//// ////
//////////////////////////////////////////////////////////////////##>
 
INCLUDE def_axi2apb.txt
OUTFILE PREFIX_axi2apb_mux.v
 
ITER SX
module PREFIX_axi2apb_mux (PORTS);
 
 
input clk;
input reset;
input [ADDR_BITS-1:0] cmd_addr;
input psel;
output [31:0] prdata;
output pready;
output pslverr;
output pselSX;
input preadySX;
input pslverrSX;
 
input [31:0] prdataSX;
 
parameter ADDR_MSB = EXPR(ADDR_BITS-1);
parameter ADDR_LSB = EXPR(ADDR_BITS-DEC_BITS);
reg pready;
reg pslverr_pre;
reg pslverr;
reg [31:0] prdata_pre;
reg [31:0] prdata;
reg [SLV_BITS-1:0] slave_num;
always @(*)
begin
casex (cmd_addr[ADDR_MSB:ADDR_LSB])
DEC_ADDRSX : slave_num = SLV_BITS'dSX;
default : slave_num = SLV_BITS'dSLAVE_NUM; //decode error
endcase
end
assign pselSX = psel & (slave_num == SLV_BITS'dSX);
always @(*)
begin
case (slave_num)
SLV_BITS'dSX: pready = preadySX;
default : pready = 1'b1; //decode error
endcase
end
always @(*)
begin
case (slave_num)
SLV_BITS'dSX: pslverr_pre = pslverrSX;
default : pslverr_pre = 1'b1; //decode error
endcase
end
always @(*)
begin
case (slave_num)
SLV_BITS'dSX: prdata_pre = prdataSX;
default : prdata_pre = {32{1'b0}};
endcase
end
always @(posedge clk or posedge reset)
if (reset)
begin
prdata <= #FFD {32{1'b0}};
pslverr <= #FFD 1'b0;
end
else if (psel & pready)
begin
prdata <= #FFD prdata_pre;
pslverr <= #FFD pslverr_pre;
end
else if (~psel)
begin
prdata <= #FFD {32{1'b0}};
pslverr <= #FFD 1'b0;
end
endmodule
 
/trunk/src/base/def_axi_master.txt
0,0 → 1,48
<##//////////////////////////////////////////////////////////////////
//// ////
//// Author: Eyal Hochberg ////
//// eyal@provartec.com ////
//// ////
//// Downloaded from: http://www.opencores.org ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2010 Provartec LTD ////
//// www.provartec.com ////
//// info@provartec.com ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation.////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more////
//// details. http://www.gnu.org/licenses/lgpl.html ////
//// ////
//////////////////////////////////////////////////////////////////##>
 
INCLUDE def_axi_master_static.txt
 
SWAP.GLOBAL #FFD #1 ##Flip-Flop simulation delay
 
SWAP PREFIX axi_master ##prefix for all module and file names
SWAP ID_BITS 4 ##AXI ID bits
SWAP ADDR_BITS 32 ##AXI address bits
SWAP DATA_BITS 64 ##AXI data bits
SWAP LEN_BITS 4 ##AXI LEN bits
SWAP SIZE_BITS 2 ##AXI SIZE bits
 
SWAP CMD_DEPTH 4 ##AXI command depth for read and write
 
SWAP ID_NUM 3 ##Number of IDs (internal masters)
SWAP ID0_VAL ID_BITS'b0011 ##AXI ID0
SWAP ID1_VAL ID_BITS'b0010 ##AXI ID1
SWAP ID2_VAL ID_BITS'b1010 ##AXI ID2
 
/trunk/src/base/def_axi2apb_static.txt
0,0 → 1,85
<##//////////////////////////////////////////////////////////////////
//// ////
//// Author: Eyal Hochberg ////
//// eyal@provartec.com ////
//// ////
//// Downloaded from: http://www.opencores.org ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2010 Provartec LTD ////
//// www.provartec.com ////
//// info@provartec.com ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation.////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more////
//// details. http://www.gnu.org/licenses/lgpl.html ////
//// ////
//////////////////////////////////////////////////////////////////##>
 
SWAP SLV_BITS LOG2(EXPR(SLAVE_NUM+1)) ##one more for decerr slave
 
LOOP SX SLAVE_NUM
 
GROUP APB3 is {
psel 1 output
penable 1 output
pwrite 1 output
paddr ADDR_BITS output
pwdata 32 output
prdata 32 input
pslverr 1 input
pready 1 input
}
 
GROUP APB_AXI_A is {
ID ID_BITS input
ADDR ADDR_BITS input
LEN 4 input
SIZE 2 input
VALID 1 input
READY 1 output
}
 
GROUP APB_AXI_W is {
ID ID_BITS input
DATA 32 input
STRB 4 input
LAST 1 input
VALID 1 input
READY 1 output
}
 
GROUP APB_AXI_B is {
ID ID_BITS output
RESP 2 output
VALID 1 output
READY 1 input
}
 
GROUP APB_AXI_R is {
ID ID_BITS output
DATA 32 output
RESP 2 output
LAST 1 output
VALID 1 output
READY 1 input
}
 
GROUP APB_AXI joins {
GROUP APB_AXI_A prefix_AW
GROUP APB_AXI_W prefix_W
GROUP APB_AXI_B prefix_B
GROUP APB_AXI_A prefix_AR
GROUP APB_AXI_R prefix_R
}
/trunk/src/base/axi2apb.v
0,0 → 1,154
<##//////////////////////////////////////////////////////////////////
//// ////
//// Author: Eyal Hochberg ////
//// eyal@provartec.com ////
//// ////
//// Downloaded from: http://www.opencores.org ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2010 Provartec LTD ////
//// www.provartec.com ////
//// info@provartec.com ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation.////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more////
//// details. http://www.gnu.org/licenses/lgpl.html ////
//// ////
//////////////////////////////////////////////////////////////////##>
 
INCLUDE def_axi2apb.txt
OUTFILE PREFIX_axi2apb.v
 
ITER SX
module PREFIX_axi2apb (PORTS);
 
input clk;
input reset;
 
port GROUP_APB_AXI;
//apb slaves
IFDEF TRUE(SLAVE_NUM==1)
port GROUP_APB3;
ELSE TRUE(SLAVE_NUM==1)
output penable;
output pwrite;
output [ADDR_BITS-1:0] paddr;
output [31:0] pwdata;
output pselSX;
input [31:0] prdataSX;
input preadySX;
input pslverrSX;
ENDIF TRUE(SLAVE_NUM==1)
 
 
 
wire GROUP_APB3;
//outputs of cmd
wire cmd_empty;
wire cmd_read;
wire [ID_BITS-1:0] cmd_id;
wire [ADDR_BITS-1:0] cmd_addr;
wire cmd_err;
//outputs of rd / wr
wire finish_wr;
wire finish_rd;
assign paddr = cmd_addr;
assign pwdata = WDATA;
 
CREATE axi2apb_cmd.v
PREFIX_axi2apb_cmd PREFIX_axi2apb_cmd(
.clk(clk),
.reset(reset),
.AWGROUP_APB_AXI_A(AWGROUP_APB_AXI_A),
.ARGROUP_APB_AXI_A(ARGROUP_APB_AXI_A),
.finish_wr(finish_wr),
.finish_rd(finish_rd),
.cmd_empty(cmd_empty),
.cmd_read(cmd_read),
.cmd_id(cmd_id),
.cmd_addr(cmd_addr),
.cmd_err(cmd_err)
);
 
CREATE axi2apb_rd.v
PREFIX_axi2apb_rd PREFIX_axi2apb_rd(
.clk(clk),
.reset(reset),
.GROUP_APB3(GROUP_APB3),
.cmd_err(cmd_err),
.cmd_id(cmd_id),
.finish_rd(finish_rd),
.RGROUP_APB_AXI_R(RGROUP_APB_AXI_R),
STOMP ,
);
CREATE axi2apb_wr.v
PREFIX_axi2apb_wr PREFIX_axi2apb_wr(
.clk(clk),
.reset(reset),
.GROUP_APB3(GROUP_APB3),
.cmd_err(cmd_err),
.cmd_id(cmd_id),
.finish_wr(finish_wr),
.WGROUP_APB_AXI_W(WGROUP_APB_AXI_W),
.BGROUP_APB_AXI_B(BGROUP_APB_AXI_B),
STOMP ,
);
 
CREATE axi2apb_ctrl.v
PREFIX_axi2apb_ctrl PREFIX_axi2apb_ctrl(
.clk(clk),
.reset(reset),
.finish_wr(finish_wr),
.finish_rd(finish_rd),
.cmd_empty(cmd_empty),
.cmd_read(cmd_read),
.WVALID(WVALID),
.psel(psel),
.penable(penable),
.pwrite(pwrite),
.pready(pready)
);
 
IFDEF TRUE(SLAVE_NUM>1)
CREATE axi2apb_mux.v
PREFIX_axi2apb_mux PREFIX_axi2apb_mux(
.clk(clk),
.reset(reset),
.cmd_addr(cmd_addr),
.psel(psel),
.prdata(prdata),
.pready(pready),
.pslverr(pslverr),
.pselSX(pselSX),
.preadySX(preadySX),
.pslverrSX(pslverrSX),
.prdataSX(prdataSX),
STOMP ,
);
ENDIF TRUE(SLAVE_NUM>1)
 
endmodule
 
 
/trunk/src/base/axi_master_stall.v
0,0 → 1,191
/////////////////////////////////////////////////////////////////////
//// ////
//// Author: Eyal Hochberg ////
//// eyal@provartec.com ////
//// ////
//// Downloaded from: http://www.opencores.org ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2010 Provartec LTD ////
//// www.provartec.com ////
//// info@provartec.com ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation.////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more////
//// details. http://www.gnu.org/licenses/lgpl.html ////
//// ////
/////////////////////////////////////////////////////////////////////
 
OUTFILE PREFIX_stall.v
 
INCLUDE def_axi_master.txt
module PREFIX_stall(PORTS);
`include "prgen_rand.v"
input clk;
input reset;
 
input rd_hold;
input wr_hold;
input ARVALID_pre;
input RREADY_pre;
input AWVALID_pre;
input WVALID_pre;
input BREADY_pre;
 
input ARREADY;
input AWREADY;
input WREADY;
output ARVALID;
output RREADY;
output AWVALID;
output WVALID;
output BREADY;
 
 
reg stall_enable = 1;
integer burst_chance = 1;
integer burst_len = 10;
integer burst_val = 90;
integer ar_stall_chance = 10;
integer r_stall_chance = 10;
integer aw_stall_chance = 10;
integer w_stall_chance = 10;
integer b_stall_chance = 10;
 
integer burst_type;
reg burst_stall;
integer ar_stall_chance_valid;
integer r_stall_chance_valid;
integer aw_stall_chance_valid;
integer w_stall_chance_valid;
integer b_stall_chance_valid;
reg ARSTALL_pre = 0;
reg RSTALL_pre = 0;
reg AWSTALL_pre = 0;
reg WSTALL_pre = 0;
reg BSTALL_pre = 0;
reg ARSTALL;
reg RSTALL;
reg AWSTALL;
reg WSTALL;
reg BSTALL;
 
 
assign ARVALID = ARVALID_pre & (~ARSTALL) & (~rd_hold);
assign RREADY = RREADY_pre & (~RSTALL);
assign AWVALID = AWVALID_pre & (~AWSTALL) & (~wr_hold);
assign WVALID = WVALID_pre & (~WSTALL);
assign BREADY = BREADY_pre & (~BSTALL);
 
 
task set_stall;
reg stall;
begin
ar_stall_chance_valid = ar_stall_chance;
r_stall_chance_valid = r_stall_chance;
aw_stall_chance_valid = aw_stall_chance;
w_stall_chance_valid = w_stall_chance;
b_stall_chance_valid = b_stall_chance;
end
endtask
 
initial
begin
#FFD;
set_stall;
 
if (burst_chance > 0)
forever
begin
burst_stall = rand_chance(burst_chance);
if (burst_stall)
begin
#FFD;
burst_type = rand(1, 5);
case (burst_type)
1 : ar_stall_chance_valid = burst_val;
2 : r_stall_chance_valid = burst_val;
3 : aw_stall_chance_valid = burst_val;
4 : w_stall_chance_valid = burst_val;
5 : b_stall_chance_valid = burst_val;
endcase
repeat (burst_len) @(posedge clk);
set_stall;
end
else
begin
@(posedge clk);
end
end
end
always @(posedge clk)
begin
#FFD;
ARSTALL_pre = rand_chance(ar_stall_chance_valid);
RSTALL_pre = rand_chance(r_stall_chance_valid);
AWSTALL_pre = rand_chance(aw_stall_chance_valid);
WSTALL_pre = rand_chance(w_stall_chance_valid);
BSTALL_pre = rand_chance(b_stall_chance_valid);
end
always @(posedge clk or posedge reset)
if (reset)
begin
ARSTALL <= #FFD 1'b0;
RSTALL <= #FFD 1'b0;
AWSTALL <= #FFD 1'b0;
WSTALL <= #FFD 1'b0;
BSTALL <= #FFD 1'b0;
end
else if (stall_enable)
begin
ARSTALL <= #FFD ARSTALL_pre & ARREADY;
RSTALL <= #FFD RSTALL_pre;
AWSTALL <= #FFD AWSTALL_pre & AWREADY;
WSTALL <= #FFD WSTALL_pre & WREADY;
BSTALL <= #FFD BSTALL_pre;
end
else
begin
ARSTALL <= #FFD 1'b0;
RSTALL <= #FFD 1'b0;
AWSTALL <= #FFD 1'b0;
WSTALL <= #FFD 1'b0;
BSTALL <= #FFD 1'b0;
end
endmodule
 
 
 
 
 
 
 
/trunk/src/base/def_axi_master_static.txt
0,0 → 1,88
<##//////////////////////////////////////////////////////////////////
//// ////
//// Author: Eyal Hochberg ////
//// eyal@provartec.com ////
//// ////
//// Downloaded from: http://www.opencores.org ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2010 Provartec LTD ////
//// www.provartec.com ////
//// info@provartec.com ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation.////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more////
//// details. http://www.gnu.org/licenses/lgpl.html ////
//// ////
//////////////////////////////////////////////////////////////////##>
 
VERIFY (DATA_BITS <= 64) else stub supports 32 or 64 bits data bus
VERIFY (SIZE_BITS <= 3) else stub supports 32 or 64 bits data bus
 
GROUP STUB_AXI_A is {
ID ID_BITS output
ADDR ADDR_BITS output
LEN LEN_BITS output
SIZE SIZE_BITS output
BURST 2 output
CACHE 4 output
PROT 3 output
LOCK 2 output
VALID 1 output
READY 1 input
}
 
GROUP STUB_AXI_W is {
ID ID_BITS output
DATA DATA_BITS output
STRB DATA_BITS/8 output
LAST 1 output
VALID 1 output
READY 1 input
}
 
GROUP STUB_AXI_B is {
ID ID_BITS input
RESP 2 input
VALID 1 input
READY 1 output
}
 
GROUP STUB_AXI_R is {
ID ID_BITS input
DATA DATA_BITS input
RESP 2 input
LAST 1 input
VALID 1 input
READY 1 output
}
 
GROUP STUB_AXI joins {
GROUP STUB_AXI_A prefix_AW
GROUP STUB_AXI_W prefix_W
GROUP STUB_AXI_B prefix_B
GROUP STUB_AXI_A prefix_AR
GROUP STUB_AXI_R prefix_R
}
 
GROUP AXI_MASTER_RAND is {
use_addr_base SON(DEFAULT 0)
len_min SON(DEFAULT 0)
len_max SON(DEFAULT 15)
size_min SON(DEFAULT 0)
size_max SON(DEFAULT 3)
addr_min SON(DEFAULT 0)
addr_max SON(DEFAULT {DATA_BITS{1'b1}})
}
/trunk/src/base/axi_master.v
0,0 → 1,336
/////////////////////////////////////////////////////////////////////
//// ////
//// Author: Eyal Hochberg ////
//// eyal@provartec.com ////
//// ////
//// Downloaded from: http://www.opencores.org ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2010 Provartec LTD ////
//// www.provartec.com ////
//// info@provartec.com ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation.////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more////
//// details. http://www.gnu.org/licenses/lgpl.html ////
//// ////
/////////////////////////////////////////////////////////////////////
 
//////////////////////////////////////
//
// General:
// The AXI master has an internal master per ID.
// These internal masters work simultaniously and an interconnect matrix connets them.
//
//
// I/F :
// idle - all internal masters emptied their command FIFOs
// scrbrd_empty - all scoreboard checks have been completed (for random testing)
//
//
// Tasks:
//
// enable(input master_num)
// Description: Enables master
// Parameters: master_num - number of internal master
//
// enable_all()
// Description: Enables all masters
//
// write_single(input master_num, input addr, input wdata)
// Description: write a single AXI burst (1 data cycle)
// Parameters: master_num - number of internal master
// addr - address
// wdata - write data
//
// read_single(input master_num, input addr, output rdata)
// Description: read a single AXI burst (1 data cycle)
// Parameters: master_num - number of internal master
// addr - address
// rdata - return read data
//
// check_single(input master_num, input addr, input expected)
// Description: read a single AXI burst and gives an error if the data read does not match expected
// Parameters: master_num - number of internal master
// addr - address
// expected - expected read data
//
// write_and_check_single(input master_num, input addr, input data)
// Description: write a single AXI burst read it back and compare the write and read data
// Parameters: master_num - number of internal master
// addr - address
// data - data to write and expect on read
//
// insert_wr_cmd(input master_num, input addr, input len, input size)
// Description: add an AXI write burst to command FIFO
// Parameters: master_num - number of internal master
// addr - address
// len - AXI LEN (data strobe number)
// size - AXI SIZE (data width)
//
// insert_rd_cmd(input master_num, input addr, input len, input size)
// Description: add an AXI read burst to command FIFO
// Parameters: master_num - number of internal master
// addr - address
// len - AXI LEN (data strobe number)
// size - AXI SIZE (data width)
//
// insert_wr_data(input master_num, input wdata)
// Description: add a single data to data FIFO (to be used in write bursts)
// Parameters: master_num - number of internal master
// wdata - write data
//
// insert_wr_incr_data(input master_num, input addr, input len, input size)
// Description: add an AXI write burst to command FIFO will use incremental data (no need to use insert_wr_data)
// Parameters: master_num - number of internal master
// addr - address
// len - AXI LEN (data strobe number)
// size - AXI SIZE (data width)
//
// insert_rand_chk(input master_num, input burst_num)
// Description: add multiple commands to command FIFO. Each command writes incremental data to a random address, reads the data back and checks the data. Useful for random testing.
// Parameters: master_num - number of internal master
// burst_num - total number of bursts to check
//
 
//
// Parameters:
//
// For random testing: (changing these values automatically update interanl masters)
// len_min - minimum burst AXI LEN (length)
// len_max - maximum burst AXI LEN (length)
// size_min - minimum burst AXI SIZE (width)
// size_max - maximum burst AXI SIZE (width)
// addr_min - minimum address (in bytes)
// addr_max - maximum address (in bytes)
//
//////////////////////////////////////
 
OUTFILE PREFIX.v
 
INCLUDE def_axi_master.txt
 
ITER IX ID_NUM
module PREFIX(PORTS);
 
input clk;
input reset;
port GROUP_STUB_AXI;
 
output idle;
output scrbrd_empty;
//random parameters
integer GROUP_AXI_MASTER_RAND = GROUP_AXI_MASTER_RAND.DEFAULT;
wire GROUP_STUB_AXI_IX;
wire idle_IX;
wire scrbrd_empty_IX;
 
 
always @(*)
begin
#FFD;
PREFIX_singleIX.GROUP_AXI_MASTER_RAND = GROUP_AXI_MASTER_RAND;
end
assign idle = CONCAT(idle_IX &);
assign scrbrd_empty = CONCAT(scrbrd_empty_IX &);
CREATE axi_master_single.v
 
LOOP IX ID_NUM
PREFIX_single #(IX, IDIX_VAL, CMD_DEPTH)
PREFIX_singleIX(
.clk(clk),
.reset(reset),
.GROUP_STUB_AXI(GROUP_STUB_AXI_IX),
.idle(idle_IX),
.scrbrd_empty(scrbrd_empty_IX)
);
ENDLOOP IX
 
IFDEF TRUE(ID_NUM==1)
assign GROUP_STUB_AXI.OUT = GROUP_STUB_AXI_0.OUT;
assign GROUP_STUB_AXI_0.IN = GROUP_STUB_AXI.IN;
ELSE TRUE(ID_NUM==1)
 
CREATE ic.v DEFCMD(SWAP.GLOBAL PARENT PREFIX) DEFCMD(SWAP.GLOBAL MASTER_NUM ID_NUM) DEFCMD(SWAP.GLOBAL CONST(ID_BITS) ID_BITS) DEFCMD(SWAP.GLOBAL CONST(CMD_DEPTH) CMD_DEPTH) DEFCMD(SWAP.GLOBAL CONST(DATA_BITS) DATA_BITS) DEFCMD(SWAP.GLOBAL CONST(ADDR_BITS) ADDR_BITS)
LOOP IX ID_NUM
STOMP NEWLINE
DEFCMD(LOOP.GLOBAL MIX_IDX 1)
STOMP NEWLINE
DEFCMD(SWAP.GLOBAL ID_MIX_ID0 IDIX_VAL)
ENDLOOP IX
 
PREFIX_ic PREFIX_ic(
.clk(clk),
.reset(reset),
.MIX_GROUP_STUB_AXI(GROUP_STUB_AXI_IX),
.S0_GROUP_STUB_AXI(GROUP_STUB_AXI),
STOMP ,
);
 
ENDIF TRUE(ID_NUM==1)
 
 
task check_master_num;
input [24*8-1:0] task_name;
input [31:0] master_num;
begin
if (master_num >= ID_NUM)
begin
$display("FATAL ERROR: task %0s called for master %0d that does not exist.\tTime: %0d ns.", task_name, master_num, $time);
end
end
endtask
task enable;
input [31:0] master_num;
begin
check_master_num("enable", master_num);
case (master_num)
IX : PREFIX_singleIX.enable = 1;
endcase
end
endtask
 
task enable_all;
begin
PREFIX_singleIX.enable = 1;
end
endtask
task write_single;
input [31:0] master_num;
input [ADDR_BITS-1:0] addr;
input [DATA_BITS-1:0] wdata;
begin
check_master_num("write_single", master_num);
case (master_num)
IX : PREFIX_singleIX.write_single(addr, wdata);
endcase
end
endtask
 
task read_single;
input [31:0] master_num;
input [ADDR_BITS-1:0] addr;
output [DATA_BITS-1:0] rdata;
begin
check_master_num("read_single", master_num);
case (master_num)
IX : PREFIX_singleIX.read_single(addr, rdata);
endcase
end
endtask
 
task check_single;
input [31:0] master_num;
input [ADDR_BITS-1:0] addr;
input [DATA_BITS-1:0] expected;
begin
check_master_num("check_single", master_num);
case (master_num)
IX : PREFIX_singleIX.check_single(addr, expected);
endcase
end
endtask
 
task write_and_check_single;
input [31:0] master_num;
input [ADDR_BITS-1:0] addr;
input [DATA_BITS-1:0] data;
begin
check_master_num("write_and_check_single", master_num);
case (master_num)
IX : PREFIX_singleIX.write_and_check_single(addr, data);
endcase
end
endtask
 
task insert_wr_cmd;
input [31:0] master_num;
input [ADDR_BITS-1:0] addr;
input [LEN_BITS-1:0] len;
input [SIZE_BITS-1:0] size;
begin
check_master_num("insert_wr_cmd", master_num);
case (master_num)
IX : PREFIX_singleIX.insert_wr_cmd(addr, len, size);
endcase
end
endtask
 
task insert_rd_cmd;
input [31:0] master_num;
input [ADDR_BITS-1:0] addr;
input [LEN_BITS-1:0] len;
input [SIZE_BITS-1:0] size;
begin
check_master_num("insert_rd_cmd", master_num);
case (master_num)
IX : PREFIX_singleIX.insert_rd_cmd(addr, len, size);
endcase
end
endtask
 
task insert_wr_data;
input [31:0] master_num;
input [DATA_BITS-1:0] wdata;
begin
check_master_num("insert_wr_data", master_num);
case (master_num)
IX : PREFIX_singleIX.insert_wr_data(wdata);
endcase
end
endtask
 
task insert_wr_incr_data;
input [31:0] master_num;
input [ADDR_BITS-1:0] addr;
input [LEN_BITS-1:0] len;
input [SIZE_BITS-1:0] size;
begin
check_master_num("insert_wr_incr_data", master_num);
case (master_num)
IX : PREFIX_singleIX.insert_wr_incr_data(addr, len, size);
endcase
end
endtask
 
task insert_rand_chk;
input [31:0] master_num;
input [31:0] burst_num;
begin
check_master_num("insert_rand_chk", master_num);
case (master_num)
IX : PREFIX_singleIX.insert_rand_chk(burst_num);
endcase
end
endtask
 
 
endmodule
 
 
/trunk/src/base/axi_master_single.v
0,0 → 1,855
/////////////////////////////////////////////////////////////////////
//// ////
//// Author: Eyal Hochberg ////
//// eyal@provartec.com ////
//// ////
//// Downloaded from: http://www.opencores.org ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2010 Provartec LTD ////
//// www.provartec.com ////
//// info@provartec.com ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation.////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more////
//// details. http://www.gnu.org/licenses/lgpl.html ////
//// ////
/////////////////////////////////////////////////////////////////////
 
OUTFILE PREFIX_single.v
 
INCLUDE def_axi_master.txt
 
module PREFIX_single(PORTS);
 
parameter MASTER_NUM = 0;
parameter MASTER_ID = 0;
parameter MASTER_PEND = 0;
`include "prgen_rand.v"
parameter MAX_CMDS = 16; //Depth of command FIFO
parameter DATA_LOG = LOG2(EXPR(DATA_BITS/8));
parameter PEND_BITS =
(MAX_CMDS <= 16) ? 4 :
(MAX_CMDS <= 32) ? 5 :
(MAX_CMDS <= 64) ? 6 :
(MAX_CMDS <= 128) ? 7 :
(MAX_CMDS <= 256) ? 8 :
(MAX_CMDS <= 512) ? 9 : 0; //0 is ilegal
input clk;
input reset;
port GROUP_STUB_AXI;
 
output idle;
output scrbrd_empty;
 
//random parameters
integer GROUP_AXI_MASTER_RAND = GROUP_AXI_MASTER_RAND.DEFAULT;
reg AWVALID_pre;
reg WVALID_pre;
wire BREADY_pre;
reg ARVALID_pre;
wire RREADY_pre;
reg enable = 0;
reg rd_enable = 0;
reg wr_enable = 0;
reg wait_for_write = 0;
reg scrbrd_enable = 0;
reg [LEN_BITS-1:0] wvalid_cnt;
 
reg rd_cmd_push = 0;
wire rd_cmd_pop;
wire [PEND_BITS:0] rd_cmd_fullness;
wire rd_cmd_empty;
wire rd_cmd_full;
reg [ADDR_BITS-1:0] rd_cmd_addr_in;
reg [LEN_BITS-1:0] rd_cmd_len_in;
reg [SIZE_BITS-1:0] rd_cmd_size_in;
wire [ADDR_BITS-1:0] rd_cmd_addr;
wire [LEN_BITS-1:0] rd_cmd_len;
wire [SIZE_BITS-1:0] rd_cmd_size;
reg rd_resp_push = 0;
wire rd_resp_pop;
wire rd_resp_empty;
wire rd_resp_full;
reg [ADDR_BITS-1:0] rd_resp_addr_in;
reg [SIZE_BITS-1:0] rd_resp_size_in;
wire [ADDR_BITS-1:0] rd_resp_addr;
wire [SIZE_BITS-1:0] rd_resp_size;
reg wr_cmd_push = 0;
wire wr_cmd_pop;
wire [PEND_BITS:0] wr_cmd_fullness;
wire wr_cmd_empty;
wire wr_cmd_full;
reg [ADDR_BITS-1:0] wr_cmd_addr_in;
reg [LEN_BITS-1:0] wr_cmd_len_in;
reg [SIZE_BITS-1:0] wr_cmd_size_in;
wire [ADDR_BITS-1:0] wr_cmd_addr;
wire [LEN_BITS-1:0] wr_cmd_len;
wire [SIZE_BITS-1:0] wr_cmd_size;
reg wr_data_push = 0;
wire wr_data_pop;
wire [PEND_BITS:0] wr_data_fullness;
wire wr_data_empty;
wire wr_data_full;
reg [ADDR_BITS-1:0] wr_data_addr_in;
reg [LEN_BITS-1:0] wr_data_len_in;
reg [SIZE_BITS-1:0] wr_data_size_in;
wire [ADDR_BITS-1:0] wr_data_addr;
wire [LEN_BITS-1:0] wr_data_len;
wire [SIZE_BITS-1:0] wr_data_size;
wire [DATA_BITS/8-1:0] wr_data_strb;
wire [7:0] wr_data_bytes;
wire [ADDR_BITS-1:0] wr_data_addr_prog;
wire [7:0] wr_data_offset;
wire wr_resp_push;
reg wr_resp_pop = 0;
wire wr_resp_empty;
wire wr_resp_full;
wire [1:0] wr_resp_resp_in;
wire [1:0] wr_resp_resp;
reg wr_fifo_push = 0;
wire wr_fifo_pop;
wire wr_fifo_empty;
wire wr_fifo_full;
reg [DATA_BITS-1:0] wr_fifo_data_in;
wire [DATA_BITS-1:0] wr_fifo_data;
wire rd_fifo_push;
reg rd_fifo_pop = 0;
wire rd_fifo_empty;
wire rd_fifo_full;
wire [DATA_BITS-1:0] rd_fifo_data_in;
wire [1:0] rd_fifo_resp_in;
wire [DATA_BITS-1:0] rd_fifo_data;
wire [1:0] rd_fifo_resp;
reg scrbrd_push = 0;
reg scrbrd_pop = 0;
wire scrbrd_empty;
wire scrbrd_full;
reg [ADDR_BITS-1:0] scrbrd_addr_in;
reg [DATA_BITS-1:0] scrbrd_data_in;
reg [DATA_BITS-1:0] scrbrd_mask_in;
wire [ADDR_BITS-1:0] scrbrd_addr;
wire [DATA_BITS-1:0] scrbrd_data;
wire [DATA_BITS-1:0] scrbrd_mask;
integer wr_fullness;
integer rd_fullness;
integer rd_completed;
integer wr_completed;
integer wr_pend_max = MASTER_PEND;
integer rd_pend_max = MASTER_PEND;
wire wr_hold;
wire rd_hold;
 
integer rand_chk_num = 0;
 
 
assign idle = rd_cmd_empty & rd_resp_empty & wr_cmd_empty & wr_data_empty & wr_resp_empty;
always @(rand_chk_num)
if (rand_chk_num > 0)
insert_rand_chk_loop(rand_chk_num);
always @(posedge enable)
begin
@(posedge clk);
wr_enable = 1;
repeat (50) @(posedge clk);
rd_enable = 1;
end
 
//for incremental data
reg [DATA_BITS-1:0] base_data = 0;
integer ww;
initial
begin
ww=0;
while (ww < DATA_BITS/8)
begin
base_data = base_data + ((MASTER_NUM + ww) << (ww*8));
ww = ww + 1;
end
end
assign rd_cmd_pop = ARVALID & ARREADY;
assign rd_resp_pop = RVALID & RREADY & RLAST;
assign rd_fifo_push = RVALID & RREADY;
assign wr_cmd_pop = AWVALID & AWREADY;
assign wr_data_pop = WVALID & WREADY & WLAST;
assign wr_fifo_pop = WVALID & WREADY;
assign wr_resp_push = BVALID & BREADY;
 
assign RREADY_pre = 1;
assign BREADY_pre = 1;
always @(posedge clk or posedge reset)
if (reset)
AWVALID_pre <= #FFD 1'b0;
else if ((wr_cmd_fullness == 1) & wr_cmd_pop)
AWVALID_pre <= #FFD 1'b0;
else if ((!wr_cmd_empty) & wr_enable)
AWVALID_pre <= #FFD 1'b1;
assign AWADDR = wr_cmd_addr;
assign AWLEN = wr_cmd_len;
assign AWSIZE = wr_cmd_size;
assign AWID = MASTER_ID;
assign AWBURST = 2'd1; //INCR only
assign AWCACHE = 4'd0; //not supported
assign AWPROT = 4'd0; //not supported
assign AWLOCK = 2'd0; //not supported
always @(posedge clk or posedge reset)
if (reset)
ARVALID_pre <= #FFD 1'b0;
else if (((rd_cmd_fullness == 1)) & rd_cmd_pop)
ARVALID_pre <= #FFD 1'b0;
else if ((!rd_cmd_empty) & rd_enable)
ARVALID_pre <= #FFD 1'b1;
 
assign ARADDR = rd_cmd_addr;
assign ARLEN = rd_cmd_len;
assign ARSIZE = rd_cmd_size;
assign ARID = MASTER_ID;
assign ARBURST = 2'd1; //INCR only
assign ARCACHE = 4'd0; //not supported
assign ARPROT = 4'd0; //not supported
assign ARLOCK = 2'd0; //not supported
 
assign rd_fifo_data_in = RDATA;
assign rd_fifo_resp_in = BRESP;
assign wr_data_bytes = 1'b1 << wr_data_size;
 
assign wr_data_strb =
wr_data_size == 'd0 ? 1'b1 :
wr_data_size == 'd1 ? 2'b11 :
wr_data_size == 'd2 ? 4'b1111 :
wr_data_size == 'd3 ? {8{1'b1}} :
wr_data_size == 'd4 ? {16{1'b1}} : 'd0;
 
assign wr_data_addr_prog = wr_data_addr + (wvalid_cnt * wr_data_bytes);
 
always @(posedge clk or posedge reset)
if (reset)
WVALID_pre <= #FFD 1'b0;
else if ((wr_data_fullness == 1) & wr_data_pop)
WVALID_pre <= #FFD 1'b0;
else if ((!wr_data_empty) & wr_enable)
WVALID_pre <= #FFD 1'b1;
 
assign wr_data_offset = wr_data_addr_prog[DATA_LOG-1:0];
assign WID = MASTER_ID;
assign WDATA = wr_fifo_empty ? 0 : wr_fifo_data;
assign WSTRB = wr_data_strb << wr_data_offset;
always @(posedge clk or posedge reset)
if (reset)
wvalid_cnt <= #FFD {LEN_BITS{1'b0}};
else if (wr_data_pop)
wvalid_cnt <= #FFD {LEN_BITS{1'b0}};
else if (WVALID & WREADY)
wvalid_cnt <= #FFD wvalid_cnt + 1'b1;
 
assign WLAST = WVALID & (wvalid_cnt == wr_data_len);
 
assign wr_resp_resp_in = BRESP;
always @(posedge clk or posedge reset)
if (reset)
begin
wr_fullness <= #FFD 0;
rd_fullness <= #FFD 0;
rd_completed <= #FFD 0;
wr_completed <= #FFD 0;
end
else
begin
wr_fullness <= #FFD wr_fullness + wr_cmd_pop - wr_resp_push;
rd_fullness <= #FFD rd_fullness + rd_cmd_pop - rd_resp_pop;
rd_completed <= #FFD rd_completed + rd_resp_pop;
wr_completed <= #FFD wr_completed + wr_resp_push;
end
assign wr_hold = wr_fullness >= wr_pend_max;
assign rd_hold = (rd_fullness >= rd_pend_max) | (wait_for_write & (wr_completed <= rd_completed + rd_fullness));
task insert_rd_cmd;
input [ADDR_BITS-1:0] addr;
input [LEN_BITS-1:0] len;
input [SIZE_BITS-1:0] size;
begin
rd_cmd_addr_in = addr;
rd_cmd_len_in = len;
rd_cmd_size_in = size;
rd_resp_addr_in = addr;
rd_resp_size_in = size;
 
if (rd_cmd_full) enable = 1; //start stub not started yet
wait ((!rd_cmd_full) & (!rd_resp_full));
@(negedge clk); #FFD;
rd_cmd_push = 1;
rd_resp_push = 1;
@(posedge clk); #FFD;
rd_cmd_push = 0;
rd_resp_push = 0;
end
endtask
task insert_wr_cmd;
input [ADDR_BITS-1:0] addr;
input [LEN_BITS-1:0] len;
input [SIZE_BITS-1:0] size;
begin
wr_cmd_addr_in = addr;
wr_cmd_len_in = len;
wr_cmd_size_in = size;
wr_data_addr_in = addr;
wr_data_len_in = len;
wr_data_size_in = size;
if (wr_cmd_full) enable = 1; //start stub not started yet
wait ((!wr_cmd_full) & (!wr_data_full));
@(negedge clk); #FFD;
wr_cmd_push = 1;
wr_data_push = 1;
@(posedge clk); #FFD;
wr_cmd_push = 0;
wr_data_push = 0;
end
endtask
 
task insert_wr_data;
input [DATA_BITS-1:0] wdata;
begin
wr_fifo_data_in = wdata;
wait (!wr_fifo_full);
@(negedge clk); #FFD;
wr_fifo_push = 1;
@(posedge clk); #FFD;
wr_fifo_push = 0;
end
endtask
 
task insert_wr_incr_data;
input [ADDR_BITS-1:0] addr;
input [LEN_BITS-1:0] len;
input [SIZE_BITS-1:0] size;
 
integer valid_cnt;
integer wdata_cnt;
reg [7:0] data_cnt;
integer bytes;
reg [DATA_BITS-1:0] add_data;
reg [DATA_BITS-1:0] next_data;
begin
//insert data
valid_cnt = 0;
while (valid_cnt <= len)
begin
bytes = 1'b1 << size;
wdata_cnt = valid_cnt+(addr[DATA_LOG-1:0]/bytes);
data_cnt = ((wdata_cnt)/(DATA_BITS/(bytes*8))) * (DATA_BITS/8);
add_data = {DATA_BITS/8{data_cnt}};
next_data = (use_addr_base ? addr : base_data) + add_data;
insert_wr_data(next_data);
valid_cnt = valid_cnt+1;
end
//insert command
insert_wr_cmd(addr, len, size);
end
endtask
task insert_scrbrd;
input [ADDR_BITS-1:0] addr;
input [DATA_BITS-1:0] data;
input [DATA_BITS-1:0] mask;
begin
scrbrd_enable = 1;
scrbrd_addr_in = addr;
scrbrd_data_in = data;
scrbrd_mask_in = mask;
wait (!scrbrd_full);
@(negedge clk); #FFD;
scrbrd_push = 1;
@(posedge clk); #FFD;
scrbrd_push = 0;
end
endtask
task insert_scrbrd_incr_data;
input [ADDR_BITS-1:0] addr;
input [LEN_BITS-1:0] len;
input [SIZE_BITS-1:0] size;
 
integer valid_cnt;
integer wdata_cnt;
reg [7:0] data_cnt;
integer bytes;
reg [DATA_BITS-1:0] add_data;
reg [DATA_BITS-1:0] next_data;
reg [DATA_BITS:0] strb;
reg [DATA_BITS-1:0] mask;
reg [ADDR_BITS-1:0] next_addr;
begin
valid_cnt = 0;
while (valid_cnt <= len)
begin
bytes = 1'b1 << size;
wdata_cnt = valid_cnt+(addr[DATA_LOG-1:0]/bytes);
data_cnt = ((wdata_cnt)/(DATA_BITS/(bytes*8))) * (DATA_BITS/8);
add_data = {DATA_BITS/8{data_cnt}};
next_data = (use_addr_base ? addr : base_data) + add_data;
next_addr = addr + (bytes * valid_cnt);
strb = (1 << (bytes*8)) - 1;
mask = strb << (next_addr[DATA_LOG-1:0]*8);
insert_scrbrd(next_addr, next_data, mask);
valid_cnt = valid_cnt+1;
end
end
endtask
task insert_rd_scrbrd;
input [ADDR_BITS-1:0] addr;
input [LEN_BITS-1:0] len;
input [SIZE_BITS-1:0] size;
 
begin
insert_scrbrd_incr_data(addr, len, size);
insert_rd_cmd(addr, len, size);
end
endtask
task insert_wr_rd_scrbrd;
input [ADDR_BITS-1:0] addr;
input [LEN_BITS-1:0] len;
input [SIZE_BITS-1:0] size;
 
begin
wait_for_write=1;
insert_wr_incr_data(addr, len, size);
insert_rd_scrbrd(addr, len, size);
end
endtask
 
task insert_wr_rd_scrbrd_rand;
reg [ADDR_BITS-1:0] addr;
reg [LEN_BITS-1:0] len;
reg [SIZE_BITS-1:0] size;
begin
len = rand(len_min, len_max);
size = rand(size_min, size_max);
addr = rand_align(addr_min, addr_max, 1 << size);
insert_wr_rd_scrbrd(addr, len, size);
end
endtask
task insert_rand_chk;
input [31:0] num;
 
rand_chk_num = num;
endtask
task insert_rand_chk_loop;
input [31:0] num;
integer i;
begin
i = 0;
while (i < num)
begin
insert_wr_rd_scrbrd_rand;
i = i + 1;
end
end
endtask
task insert_wr_single;
input [ADDR_BITS-1:0] addr;
input [DATA_BITS-1:0] wdata;
 
reg [SIZE_BITS-1:0] size;
begin
size = EXPR((DATA_BITS/32)+1);
insert_wr_data(wdata);
insert_wr_cmd(addr, 0, size);
end
endtask
 
task get_rd_resp;
output [DATA_BITS-1:0] rdata;
output [1:0] resp;
reg [DATA_BITS-1:0] rdata;
reg [1:0] resp;
begin
wait (!rd_fifo_empty);
rdata = rd_fifo_data;
resp = rd_fifo_resp;
@(negedge clk); #FFD;
rd_fifo_pop = 1;
@(posedge clk); #FFD;
rd_fifo_pop = 0;
end
endtask
task get_scrbrd;
output [ADDR_BITS-1:0] addr;
output [DATA_BITS-1:0] rdata;
output [DATA_BITS-1:0] mask;
reg [ADDR_BITS-1:0] addr;
reg [DATA_BITS-1:0] rdata;
reg [DATA_BITS-1:0] mask;
begin
wait (!scrbrd_empty);
addr = scrbrd_addr;
rdata = scrbrd_data;
mask = scrbrd_mask;
@(negedge clk); #FFD;
scrbrd_pop = 1;
@(posedge clk); #FFD;
scrbrd_pop = 0;
end
endtask
task get_wr_resp;
output [1:0] resp;
 
reg [1:0] resp;
begin
wait (!wr_resp_empty);
resp = wr_resp_resp;
@(negedge clk); #FFD;
wr_resp_pop = 1;
@(posedge clk); #FFD;
wr_resp_pop = 0;
end
endtask
task insert_rd_single;
input [ADDR_BITS-1:0] addr;
 
reg [SIZE_BITS-1:0] size;
begin
size = EXPR((DATA_BITS/32)+1);
insert_rd_cmd(addr, 0, size);
end
endtask
 
task read_single_ack;
input [ADDR_BITS-1:0] addr;
output [DATA_BITS-1:0] rdata;
output [1:0] resp;
reg [1:0] resp;
begin
insert_rd_single(addr);
get_rd_resp(rdata, resp);
end
endtask
task write_single_ack;
input [ADDR_BITS-1:0] addr;
input [DATA_BITS-1:0] wdata;
output [1:0] resp;
 
reg [1:0] resp;
begin
insert_wr_single(addr, wdata);
get_wr_resp(resp);
end
endtask
task read_single;
input [ADDR_BITS-1:0] addr;
output [DATA_BITS-1:0] rdata;
reg [1:0] resp;
begin
read_single_ack(addr, rdata, resp);
end
endtask
task check_single;
input [ADDR_BITS-1:0] addr;
input [DATA_BITS-1:0] expected;
reg [1:0] resp;
reg [DATA_BITS-1:0] rdata;
begin
read_single_ack(addr, rdata, resp);
if (rdata !== expected)
$display("MASTER%0d: CHK_SINGLE_ERROR: Address: 0x%0h, Expected: 0x%0h, Received: 0x%0h.\tTime: %0d ns.", MASTER_NUM, addr, expected, rdata, $time);
end
endtask
task write_and_check_single;
input [ADDR_BITS-1:0] addr;
input [DATA_BITS-1:0] data;
begin
write_single(addr, data);
check_single(addr, data);
end
endtask
task write_single;
input [ADDR_BITS-1:0] addr;
input [DATA_BITS-1:0] wdata;
 
reg [1:0] resp;
begin
write_single_ack(addr, wdata, resp);
end
endtask
 
task chk_scrbrd;
reg [ADDR_BITS-1:0] addr;
reg [DATA_BITS-1:0] mask;
reg [DATA_BITS-1:0] expected_data;
reg [DATA_BITS-1:0] rdata;
reg [DATA_BITS-1:0] rdata_masked;
reg [1:0] resp;
begin
if (!wr_resp_empty) get_wr_resp(resp);
get_scrbrd(addr, expected_data, mask);
get_rd_resp(rdata, resp);
expected_data = expected_data & mask; //TBD insert z as dontcare (for print)
rdata_masked = rdata & mask;
if (expected_data !== rdata_masked)
$display("MASTER%0d: SCRBRD_ERROR: Address: 0x%0h, Expected: 0x%0h, Received: 0x%0h.\tTime: %0d ns.", MASTER_NUM, addr, expected_data, rdata, $time);
end
endtask
 
always @(posedge scrbrd_enable)
begin
while (scrbrd_enable)
begin
chk_scrbrd;
end
end
 
CREATE prgen_fifo.v DEFCMD(DEFINE STUB)
prgen_fifo_stub #(ADDR_BITS+LEN_BITS+SIZE_BITS, MAX_CMDS)
rd_cmd_list(
.clk(clk),
.reset(reset),
.push(rd_cmd_push),
.pop(rd_cmd_pop),
.din({
rd_cmd_size_in,
rd_cmd_len_in,
rd_cmd_addr_in
}),
.dout({
rd_cmd_size,
rd_cmd_len,
rd_cmd_addr
}),
.fullness(rd_cmd_fullness),
.empty(rd_cmd_empty),
.full(rd_cmd_full)
);
 
prgen_fifo_stub #(ADDR_BITS+SIZE_BITS, MAX_CMDS)
rd_resp_list(
.clk(clk),
.reset(reset),
.push(rd_resp_push),
.pop(rd_resp_pop),
.din({
rd_resp_addr_in,
rd_resp_size_in
}),
.dout({
rd_resp_addr,
rd_resp_size
}),
.empty(rd_resp_empty),
.full(rd_resp_full)
);
 
prgen_fifo_stub #(ADDR_BITS+LEN_BITS+SIZE_BITS, MAX_CMDS)
wr_cmd_list(
.clk(clk),
.reset(reset),
.push(wr_cmd_push),
.pop(wr_cmd_pop),
.din({
wr_cmd_size_in,
wr_cmd_len_in,
wr_cmd_addr_in
}),
.dout({
wr_cmd_size,
wr_cmd_len,
wr_cmd_addr
}),
.fullness(wr_cmd_fullness),
.empty(wr_cmd_empty),
.full(wr_cmd_full)
);
 
prgen_fifo_stub #(ADDR_BITS+LEN_BITS+SIZE_BITS, MAX_CMDS)
wr_data_list(
.clk(clk),
.reset(reset),
.push(wr_data_push),
.pop(wr_data_pop),
.din({
wr_data_size_in,
wr_data_len_in,
wr_data_addr_in
}),
.dout({
wr_data_size,
wr_data_len,
wr_data_addr
}),
.fullness(wr_data_fullness),
.empty(wr_data_empty),
.full(wr_data_full)
);
 
prgen_fifo_stub #(2, MAX_CMDS)
wr_resp_list(
.clk(clk),
.reset(reset),
.push(wr_resp_push),
.pop(wr_resp_pop),
.din(wr_resp_resp_in),
.dout(wr_resp_resp),
.empty(wr_resp_empty),
.full(wr_resp_full)
);
 
prgen_fifo_stub #(DATA_BITS, MAX_CMDS*EXPR(2^LEN_BITS))
wr_data_fifo(
.clk(clk),
.reset(reset),
.push(wr_fifo_push),
.pop(wr_fifo_pop),
.din(wr_fifo_data_in),
.dout(wr_fifo_data),
.empty(wr_fifo_empty),
.full(wr_fifo_full)
);
 
prgen_fifo_stub #(DATA_BITS+2, MAX_CMDS*EXPR(2^LEN_BITS))
rd_data_fifo(
.clk(clk),
.reset(reset),
.push(rd_fifo_push),
.pop(rd_fifo_pop),
.din({
rd_fifo_data_in,
rd_fifo_resp_in
}),
.dout({
rd_fifo_data,
rd_fifo_resp
}),
.empty(rd_fifo_empty),
.full(rd_fifo_full)
);
 
prgen_fifo_stub #(ADDR_BITS+2*DATA_BITS, MAX_CMDS*EXPR(2^LEN_BITS))
scrbrd_fifo(
.clk(clk),
.reset(reset),
.push(scrbrd_push),
.pop(scrbrd_pop),
.din({
scrbrd_addr_in,
scrbrd_data_in,
scrbrd_mask_in
}),
.dout({
scrbrd_addr,
scrbrd_data,
scrbrd_mask
}),
.empty(scrbrd_empty),
.full(scrbrd_full)
);
 
 
CREATE axi_master_stall.v
PREFIX_stall
PREFIX_stall (
.clk(clk),
.reset(reset),
 
.rd_hold(rd_hold),
.wr_hold(wr_hold),
.ARVALID_pre(ARVALID_pre),
.RREADY_pre(RREADY_pre),
.AWVALID_pre(AWVALID_pre),
.WVALID_pre(WVALID_pre),
.BREADY_pre(BREADY_pre),
.ARREADY(ARREADY),
.AWREADY(AWREADY),
.WREADY(WREADY),
.ARVALID(ARVALID),
.RREADY(RREADY),
.AWVALID(AWVALID),
.WVALID(WVALID),
.BREADY(BREADY)
);
 
 
endmodule
 
 
/trunk/src/base/axi2apb_wr.v
0,0 → 1,77
<##//////////////////////////////////////////////////////////////////
//// ////
//// Author: Eyal Hochberg ////
//// eyal@provartec.com ////
//// ////
//// Downloaded from: http://www.opencores.org ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2010 Provartec LTD ////
//// www.provartec.com ////
//// info@provartec.com ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation.////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more////
//// details. http://www.gnu.org/licenses/lgpl.html ////
//// ////
//////////////////////////////////////////////////////////////////##>
 
INCLUDE def_axi2apb.txt
OUTFILE PREFIX_axi2apb_wr.v
 
module PREFIX_axi2apb_wr (PORTS);
 
input clk;
input reset;
input GROUP_APB3;
input cmd_err;
input [ID_BITS-1:0] cmd_id;
output finish_wr;
port WGROUP_APB_AXI_W;
port BGROUP_APB_AXI_B;
parameter RESP_OK = 2'b00;
parameter RESP_SLVERR = 2'b10;
parameter RESP_DECERR = 2'b11;
reg BGROUP_APB_AXI_B.OUT;
assign finish_wr = BVALID & BREADY;
assign WREADY = psel & penable & pwrite & pready;
always @(posedge clk or posedge reset)
if (reset)
begin
BGROUP_APB_AXI_B.OUT <= #FFD {GROUP_APB_AXI_B.OUT.WIDTH{1'b0}};
end
else if (finish_wr)
begin
BGROUP_APB_AXI_B.OUT <= #FFD {GROUP_APB_AXI_B.OUT.WIDTH{1'b0}};
end
else if (psel & penable & pwrite & pready)
begin
BID <= #FFD cmd_id;
BRESP <= #FFD cmd_err ? RESP_SLVERR : pslverr ? RESP_DECERR : RESP_OK;
BVALID <= #FFD 1'b1;
end
endmodule
 
/trunk/src/base/def_apb_master.txt
0,0 → 1,37
<##//////////////////////////////////////////////////////////////////
//// ////
//// Author: Eyal Hochberg ////
//// eyal@provartec.com ////
//// ////
//// Downloaded from: http://www.opencores.org ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2010 Provartec LTD ////
//// www.provartec.com ////
//// info@provartec.com ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation.////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more////
//// details. http://www.gnu.org/licenses/lgpl.html ////
//// ////
//////////////////////////////////////////////////////////////////##>
 
INCLUDE def_apb_master_static.txt
 
SWAP.GLOBAL #FFD #1 ##Flip-flop delay
SWAP.GLOBAL ADDR_BITS 16 ##APB address bits
 
##DEFINE APB3 ##if set use pready and pslverr APB3 signals
/trunk/src/base/axi2apb_cmd.v
0,0 → 1,115
<##//////////////////////////////////////////////////////////////////
//// ////
//// Author: Eyal Hochberg ////
//// eyal@provartec.com ////
//// ////
//// Downloaded from: http://www.opencores.org ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2010 Provartec LTD ////
//// www.provartec.com ////
//// info@provartec.com ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation.////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more////
//// details. http://www.gnu.org/licenses/lgpl.html ////
//// ////
//////////////////////////////////////////////////////////////////##>
 
INCLUDE def_axi2apb.txt
OUTFILE PREFIX_axi2apb_cmd.v
 
module PREFIX_axi2apb_cmd (PORTS);
 
input clk;
input reset;
 
port AWGROUP_APB_AXI_A;
port ARGROUP_APB_AXI_A;
input finish_wr;
input finish_rd;
output cmd_empty;
output cmd_read;
output [ID_BITS-1:0] cmd_id;
output [ADDR_BITS-1:0] cmd_addr;
output cmd_err;
wire AGROUP_APB_AXI_A;
wire cmd_push;
wire cmd_pop;
wire cmd_empty;
wire cmd_full;
reg read;
wire wreq, rreq;
wire wack, rack;
wire AERR;
assign wreq = AWVALID;
assign rreq = ARVALID;
assign wack = AWVALID & AWREADY;
assign rack = ARVALID & ARREADY;
always @(posedge clk or posedge reset)
if (reset)
read <= #FFD 1'b1;
else if (wreq & (rack | (~rreq)))
read <= #FFD 1'b0;
else if (rreq & (wack | (~wreq)))
read <= #FFD 1'b1;
 
//command mux
assign AGROUP_APB_AXI_A = read ? ARGROUP_APB_AXI_A : AWGROUP_APB_AXI_A;
assign AERR = (ASIZE != 'd2) | (ALEN != 'd0); //support only 32 bit single AXI commands
assign ARREADY = (~cmd_full) & read;
assign AWREADY = (~cmd_full) & (~read);
assign cmd_push = AVALID & AREADY;
assign cmd_pop = cmd_read ? finish_rd : finish_wr;
CREATE prgen_fifo.v DEFCMD(SWAP CONST(#FFD) #FFD)
prgen_fifo #(ID_BITS+ADDR_BITS+2, CMD_DEPTH)
cmd_fifo(
.clk(clk),
.reset(reset),
.push(cmd_push),
.pop(cmd_pop),
.din({
AID,
AADDR,
AERR,
read
}
),
.dout({
cmd_id,
cmd_addr,
cmd_err,
cmd_read
}
),
.empty(cmd_empty),
.full(cmd_full)
);
 
endmodule
 
 
/trunk/src/base/axi2apb_ctrl.v
0,0 → 1,104
<##//////////////////////////////////////////////////////////////////
//// ////
//// Author: Eyal Hochberg ////
//// eyal@provartec.com ////
//// ////
//// Downloaded from: http://www.opencores.org ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2010 Provartec LTD ////
//// www.provartec.com ////
//// info@provartec.com ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer.////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation.////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more////
//// details. http://www.gnu.org/licenses/lgpl.html ////
//// ////
//////////////////////////////////////////////////////////////////##>
 
INCLUDE def_axi2apb.txt
OUTFILE PREFIX_axi2apb_ctrl.v
 
module PREFIX_axi2apb_ctrl (PORTS);
 
 
input clk;
input reset;
 
input finish_wr;
input finish_rd;
input cmd_empty;
input cmd_read;
input WVALID;
 
output psel;
output penable;
output pwrite;
input pready;
wire wstart;
wire rstart;
reg busy;
reg psel;
reg penable;
reg pwrite;
wire pack;
wire cmd_ready;
 
assign cmd_ready = (~busy) & (~cmd_empty);
assign wstart = cmd_ready & (~cmd_read) & (~psel) & WVALID;
assign rstart = cmd_ready & cmd_read & (~psel);
assign pack = psel & penable & pready;
always @(posedge clk or posedge reset)
if (reset)
busy <= #FFD 1'b0;
else if (psel)
busy <= #FFD 1'b1;
else if (finish_rd | finish_wr)
busy <= #FFD 1'b0;
always @(posedge clk or posedge reset)
if (reset)
psel <= #FFD 1'b0;
else if (pack)
psel <= #FFD 1'b0;
else if (wstart | rstart)
psel <= #FFD 1'b1;
always @(posedge clk or posedge reset)
if (reset)
penable <= #FFD 1'b0;
else if (pack)
penable <= #FFD 1'b0;
else if (psel)
penable <= #FFD 1'b1;
 
always @(posedge clk or posedge reset)
if (reset)
pwrite <= #FFD 1'b0;
else if (pack)
pwrite <= #FFD 1'b0;
else if (wstart)
pwrite <= #FFD 1'b1;
 
endmodule
 
/trunk/README.txt
0,0 → 1,22
 
------------------------------ Remark ----------------------------------------
This code is a generic code written in RobustVerilog. In order to convert it to Verilog a RobustVerilog parser is required.
It is possible to download a free RobustVerilog parser from www.provartec.com/edatools.
 
We will be very happy to receive any kind of feedback regarding our tools and cores.
We will also be willing to support any company intending to integrate our cores into their project.
For any questions / remarks / suggestions / bugs please contact info@provartec.com.
------------------------------------------------------------------------------
 
RobustVerilog generic APB master stub
 
The APB master is built out of an AXI master and an AXI2APB bridge (both independent OpenCores projects)
 
In order to create the Verilog design use the run.sh script in the run directory (notice that the run scripts calls the robust binary (RobustVerilog parser)).
 
The RobustVerilog top source file is apb_master.v, it calls the top definition file named def_apb_master.txt.
 
Changing the stub parameters should be made only in def_apb_master.txt in the src/base directory (changing to APB3, address bits, etc.).
 
Once the Verilog files have been generated instruction on how to use the stub are at the top of apb_master.v (tasks and parameters).
 

powered by: WebSVN 2.1.0

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