URL
https://opencores.org/ocsvn/axi_master/axi_master/trunk
Subversion Repositories axi_master
Compare Revisions
- This comparison shows the changes necessary to convert path
/axi_master/trunk
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/run/run.sh
0,0 → 1,9
#!/bin/bash |
|
echo Starting RobustVerilog axi master run |
rm -rf out |
mkdir out |
|
../../../robust ../src/base/axi_master.v -od out -I ../src/gen -list filelist.txt -listpath -header |
|
echo Completed RobustVerilog axi fabric run - results in run/out/ |
/src/base/ic_wdata.v
0,0 → 1,109
<##////////////////////////////////////////////////////////////////// |
//// //// |
//// 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_ic_wdata.v |
|
ITER MX |
ITER SX |
|
module PREFIX_ic_wdata (PORTS); |
|
parameter STRB_BITS = DATA_BITS/8; |
|
input clk; |
input reset; |
|
port MMX_AWGROUP_IC_AXI_CMD; |
port MMX_WGROUP_IC_AXI_W; |
revport SSX_WGROUP_IC_AXI_W; |
input SSX_AWVALID; |
input SSX_AWREADY; |
input [MSTR_BITS-1:0] SSX_AWMSTR; |
|
|
parameter WBUS_WIDTH = GONCAT(GROUP_IC_AXI_W.IN.WIDTH +); |
|
|
wire [WBUS_WIDTH-1:0] SSX_WBUS; |
|
wire [WBUS_WIDTH-1:0] MMX_WBUS; |
|
wire [SLV_BITS-1:0] MMX_WSLV; |
wire MMX_WOK; |
|
wire SSX_MMX; |
|
|
|
|
CREATE ic_registry_wr.v def_ic.txt |
PREFIX_ic_registry_wr |
PREFIX_ic_registry_wr ( |
.clk(clk), |
.reset(reset), |
.MMX_AWSLV(MMX_AWSLV), |
.MMX_AWID(MMX_AWID), |
.MMX_AWVALID(MMX_AWVALID), |
.MMX_AWREADY(MMX_AWREADY), |
.MMX_WID(MMX_WID), |
.MMX_WVALID(MMX_WVALID), |
.MMX_WREADY(MMX_WREADY), |
.MMX_WLAST(MMX_WLAST), |
.MMX_WSLV(MMX_WSLV), |
.MMX_WOK(MMX_WOK), |
.SSX_AWVALID(SSX_AWVALID), |
.SSX_AWREADY(SSX_AWREADY), |
.SSX_AWMSTR(SSX_AWMSTR), |
.SSX_WVALID(SSX_WVALID), |
.SSX_WREADY(SSX_WREADY), |
.SSX_WLAST(SSX_WLAST), |
STOMP , |
); |
|
|
|
assign SSX_MMX = (MMX_WSLV == 'dSX) & MMX_WOK & MMX_WVALID; |
|
assign MMX_WBUS = {GONCAT(MMX_WGROUP_IC_AXI_W.IN ,)}; |
|
assign SSX_WBUS = CONCAT((MMX_WBUS & {WBUS_WIDTH{SSX_MMX}}) |); |
|
assign {GONCAT(SSX_WGROUP_IC_AXI_W.IN ,)} = SSX_WBUS; |
|
LOOP MX |
assign MMX_WREADY = |
SSX_MMX ? SSX_WREADY : |
1'b0; |
|
ENDLOOP MX |
|
endmodule |
|
|
|
/src/base/ic_registry_resp.v
0,0 → 1,163
<##////////////////////////////////////////////////////////////////// |
//// //// |
//// 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_ic_registry_resp.v |
|
ITER MX |
ITER SX |
|
LOOP MX |
ITER MMX_IDX |
ENDLOOP MX |
|
module PREFIX_ic_registry_resp(PORTS); |
|
input clk; |
input reset; |
|
port MMX_AGROUP_IC_AXI_CMD; |
|
input [ID_BITS-1:0] SSX_ID; |
input SSX_VALID; |
input SSX_READY; |
input SSX_LAST; |
output [MSTR_BITS-1:0] SSX_MSTR; |
output SSX_OK; |
|
|
|
wire Amatch_MMX_IDMMX_IDX; |
wire match_MMX_IDMMX_IDX; |
wire no_Amatch_MMX; |
|
wire cmd_push_MMX; |
wire cmd_push_MMX_IDMMX_IDX; |
|
wire cmd_pop_SSX; |
LOOP MX |
wire cmd_pop_MMX_IDMMX_IDX; |
ENDLOOP MX |
|
wire [SLV_BITS-1:0] slave_in_MMX_IDMMX_IDX; |
wire [SLV_BITS-1:0] slave_out_MMX_IDMMX_IDX; |
wire slave_empty_MMX_IDMMX_IDX; |
wire slave_full_MMX_IDMMX_IDX; |
|
reg [MSTR_BITS-1:0] ERR_MSTR_reg; |
wire [MSTR_BITS-1:0] ERR_MSTR; |
|
reg [MSTR_BITS-1:0] SSX_MSTR; |
reg SSX_OK; |
|
|
|
|
assign Amatch_MMX_IDMMX_IDX = MMX_AID == ID_MMX_IDMMX_IDX; |
|
assign match_MMX_IDMMX_IDX = SSX_ID == ID_MMX_IDMMX_IDX; |
|
|
assign cmd_push_MMX = MMX_AVALID & MMX_AREADY; |
assign cmd_push_MMX_IDMMX_IDX = cmd_push_MMX & Amatch_MMX_IDMMX_IDX; |
assign cmd_pop_SSX = SSX_VALID & SSX_READY & SSX_LAST; |
|
LOOP MX |
assign cmd_pop_MMX_IDMMX_IDX = CONCAT((cmd_pop_SSX & (SSX_ID == ID_MMX_IDMMX_IDX)) |); |
ENDLOOP MX |
|
|
assign slave_in_MMX_IDMMX_IDX = MMX_ASLV; |
|
|
|
|
IFDEF DEF_DECERR_SLV |
LOOP MX |
assign no_Amatch_MMX = CONCAT((~Amatch_MMX_IDMMX_IDX) &); |
ENDLOOP MX |
|
|
always @(posedge clk or posedge reset) |
if (reset) |
ERR_MSTR_reg <= #FFD {MSTR_BITS{1'b0}}; |
LOOP MX |
else if (cmd_push_MMX & no_Amatch_MMX) |
ERR_MSTR_reg <= #FFD 'dMX; |
ENDLOOP MX |
|
assign ERR_MSTR = ERR_MSTR_reg; |
ELSE DEF_DECERR_SLV |
assign ERR_MSTR = 'd0; |
ENDIF DEF_DECERR_SLV |
|
|
LOOP SX |
always @(SSX_ID or ERR_MSTR) |
begin |
case (SSX_ID) |
LOOP MX |
ID_MMX_IDMMX_IDX : SSX_MSTR = 'dMX; |
ENDLOOP MX |
default : SSX_MSTR = ERR_MSTR; |
endcase |
end |
|
always @(*) |
begin |
case (SSX_ID) |
LOOP MX |
ID_MMX_IDMMX_IDX : SSX_OK = slave_out_MMX_IDMMX_IDX == 'dSX; |
ENDLOOP MX |
default : SSX_OK = 1'b1; //SLVERR |
endcase |
end |
ENDLOOP SX |
|
CREATE prgen_fifo.v DEFCMD(SWAP CONST(#FFD) #FFD) |
LOOP MX |
LOOP MMX_IDX |
prgen_fifo #(SLV_BITS, CMD_DEPTH) |
slave_fifo_MMX_IDMMX_IDX( |
.clk(clk), |
.reset(reset), |
.push(cmd_push_MMX_IDMMX_IDX), |
.pop(cmd_pop_MMX_IDMMX_IDX), |
.din(slave_in_MMX_IDMMX_IDX), |
.dout(slave_out_MMX_IDMMX_IDX), |
.empty(slave_empty_MMX_IDMMX_IDX), |
.full(slave_full_MMX_IDMMX_IDX) |
); |
|
ENDLOOP MMX_IDX |
ENDLOOP MX |
|
|
endmodule |
|
|
/src/base/ic_decerr.v
0,0 → 1,140
<##////////////////////////////////////////////////////////////////// |
//// //// |
//// 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_ic_decerr.v |
|
module PREFIX_ic_decerr(PORTS); |
|
input clk; |
input reset; |
|
input AWIDOK; |
input ARIDOK; |
port GROUP_IC_AXI; |
|
|
parameter RESP_SLVERR = 2'b10; |
parameter RESP_DECERR = 2'b11; |
|
|
reg AWREADY; |
reg [ID_BITS-1:0] BID; |
reg [1:0] BRESP; |
reg BVALID; |
reg ARREADY; |
reg [ID_BITS-1:0] RID; |
reg [1:0] RRESP; |
reg RVALID; |
reg [4-1:0] rvalid_cnt; |
|
|
assign BUSER = 'd0; |
assign RUSER = 'd0; |
assign RDATA = {DATA_BITS{1'b0}}; |
|
|
//WRITE |
assign WREADY = 1'b1; |
|
always @(posedge clk or posedge reset) |
if (reset) |
begin |
AWREADY <= #FFD 1'b1; |
BID <= #FFD {ID_BITS{1'b0}}; |
BRESP <= #FFD 2'b00; |
end |
else if (BVALID & BREADY) |
begin |
AWREADY <= #FFD 1'b1; |
end |
else if (AWVALID & AWREADY) |
begin |
AWREADY <= #FFD 1'b0; |
BID <= #FFD AWID; |
BRESP <= #FFD AWIDOK ? RESP_DECERR : RESP_SLVERR; |
end |
|
always @(posedge clk or posedge reset) |
if (reset) |
BVALID <= #FFD 1'b0; |
else if (WVALID & WREADY & WLAST) |
BVALID <= #FFD 1'b1; |
else if (BVALID & BREADY) |
BVALID <= #FFD 1'b0; |
|
|
//READ |
always @(posedge clk or posedge reset) |
if (reset) |
begin |
ARREADY <= #FFD 1'b1; |
RID <= #FFD {ID_BITS{1'b0}}; |
RRESP <= #FFD 2'b00; |
end |
else if (RVALID & RREADY & RLAST) |
begin |
ARREADY <= #FFD 1'b1; |
end |
else if (ARVALID & ARREADY) |
begin |
ARREADY <= #FFD 1'b0; |
RID <= #FFD ARID; |
RRESP <= #FFD ARIDOK ? RESP_DECERR : RESP_SLVERR; |
end |
|
|
always @(posedge clk or posedge reset) |
if (reset) |
rvalid_cnt <= #FFD {4{1'b0}}; |
else if (RVALID & RREADY & RLAST) |
rvalid_cnt <= #FFD {4{1'b0}}; |
else if (RVALID & RREADY) |
rvalid_cnt <= #FFD rvalid_cnt - 1'b1; |
else if (ARVALID & ARREADY) |
rvalid_cnt <= #FFD ARLEN; |
|
|
always @(posedge clk or posedge reset) |
if (reset) |
RVALID <= #FFD 1'b0; |
else if (RVALID & RREADY & RLAST) |
RVALID <= #FFD 1'b0; |
else if (ARVALID & ARREADY) |
RVALID <= #FFD 1'b1; |
|
assign RLAST = (rvalid_cnt == 'd0) & RVALID; |
|
|
|
|
|
|
endmodule |
|
|
/src/base/def_ic.txt
0,0 → 1,36
<##////////////////////////////////////////////////////////////////// |
//// //// |
//// 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_ic_static.txt |
|
SWAP PREFIX PARENT ##prefix for all module and file names |
|
SWAP SLAVE_NUM 1 ##number of slaves |
|
SWAP USER_BITS 0 ##AXI user bits |
/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 |
|
/src/base/ic_resp.v
0,0 → 1,124
<##////////////////////////////////////////////////////////////////// |
//// //// |
//// 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_ic_resp.v |
|
ITER MX |
ITER SX |
|
module PREFIX_ic_resp (PORTS); |
|
parameter STRB_BITS = DATA_BITS/8; |
|
input clk; |
input reset; |
|
port MMX_AGROUP_IC_AXI_CMD; |
port MMX_GROUP_IC_AXI_R; |
revport SSX_GROUP_IC_AXI_R; |
|
|
parameter RBUS_WIDTH = GONCAT(GROUP_IC_AXI_R.OUT.WIDTH +); |
|
wire SSX_req; |
|
wire [RBUS_WIDTH-1:0] SSX_RBUS; |
|
wire [RBUS_WIDTH-1:0] MMX_RBUS; |
|
wire SSX_MMX; |
|
wire [MSTR_BITS-1:0] SSX_MSTR; |
wire SSX_OK; |
|
wire [SLVS-1:0] MMX_slave; |
|
|
|
|
|
CREATE ic_registry_resp.v def_ic.txt |
PREFIX_ic_registry_resp |
PREFIX_ic_registry_resp ( |
.clk(clk), |
.reset(reset), |
.MMX_ASLV(MMX_ASLV), |
.MMX_AID(MMX_AID), |
.MMX_AVALID(MMX_AVALID), |
.MMX_AREADY(MMX_AREADY), |
.SSX_ID(SSX_ID), |
.SSX_VALID(SSX_VALID), |
.SSX_READY(SSX_READY), |
.SSX_LAST(SSX_LAST), |
.SSX_MSTR(SSX_MSTR), |
.SSX_OK(SSX_OK), |
STOMP , |
); |
|
|
CREATE ic_arbiter.v def_ic.txt DEFCMD(SWAP MSTR_SLV slv) DEFCMD(SWAP MSTRNUM SLVS) DEFCMD(SWAP SLVNUM MSTRS) DEFCMD(DEFINE DEF_PRIO) |
PREFIX_ic_slv_arbiter |
PREFIX_ic_slv_arbiter( |
.clk(clk), |
.reset(reset), |
|
.MSX_slave(SSX_MSTR), |
|
.SMX_master(MMX_slave), |
|
.M_last({CONCAT(SSX_LAST ,)}), |
.M_req({CONCAT(SSX_req ,)}), |
.M_grant({CONCAT(SSX_READY ,)}) |
); |
|
|
assign SSX_req = SSX_VALID & SSX_OK; |
|
assign SSX_MMX = MMX_slave[SX]; |
|
|
assign SSX_RBUS = {GONCAT(SSX_GROUP_IC_AXI_R.OUT ,)}; |
|
assign {GONCAT(MMX_GROUP_IC_AXI_R.OUT ,)} = MMX_RBUS; |
|
LOOP MX |
assign MMX_RBUS = CONCAT((SSX_RBUS & {RBUS_WIDTH{SSX_MMX}}) |); |
|
ENDLOOP MX |
|
|
LOOP SX |
assign SSX_READY = CONCAT((SSX_MMX & MMX_READY) |); |
|
ENDLOOP SX |
|
endmodule |
|
|
|
/src/base/ic_addr.v
0,0 → 1,127
<##////////////////////////////////////////////////////////////////// |
//// //// |
//// 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_ic_addr.v |
|
ITER MX |
ITER SX |
|
module PREFIX_ic_addr (PORTS); |
|
input clk; |
input reset; |
|
output [EXPR(SLV_BITS-1):0] MMX_ASLV; |
port MMX_AGROUP_IC_AXI_A; |
output [EXPR(MSTR_BITS-1):0] SSX_AMSTR; |
output SSX_AIDOK; |
revport SSX_AGROUP_IC_AXI_A; |
|
|
parameter MASTER_NONE = 0; |
parameter MASTERMX = 1 << MX; |
|
parameter ABUS_WIDTH = GONCAT(GROUP_IC_AXI_A.IN.WIDTH +); |
|
|
wire [ABUS_WIDTH-1:0] SSX_ABUS; |
|
wire [ABUS_WIDTH-1:0] MMX_ABUS; |
|
wire SSX_MMX; |
|
wire [EXPR(SLV_BITS-1):0] MMX_ASLV; |
|
wire MMX_AIDOK; |
|
wire [EXPR(MSTRS-1):0] SSX_master; |
|
reg [EXPR(MSTR_BITS-1):0] SSX_AMSTR; |
|
wire SSX_AIDOK; |
|
CREATE ic_dec.v def_ic.txt |
PREFIX_ic_dec |
PREFIX_ic_dec ( |
.MMX_AADDR(MMX_AADDR), |
.MMX_AID(MMX_AID), |
.MMX_ASLV(MMX_ASLV), |
.MMX_AIDOK(MMX_AIDOK), |
STOMP , |
); |
|
|
CREATE ic_arbiter.v def_ic.txt DEFCMD(SWAP MSTR_SLV mstr) DEFCMD(SWAP MSTRNUM MSTRS) DEFCMD(SWAP SLVNUM SLVS) DEFCMD(DEFINE DEF_PRIO) |
PREFIX_ic_mstr_arbiter |
PREFIX_ic_mstr_arbiter( |
.clk(clk), |
.reset(reset), |
|
.MMX_slave(MMX_ASLV), |
|
.SSX_master(SSX_master), |
|
.M_last({MSTRS{1'b1}}), |
.M_req({CONCAT(MMX_AVALID ,)}), |
.M_grant({CONCAT(MMX_AREADY ,)}) |
); |
|
LOOP SX |
always @(/*AUTOSENSE*/SSX_master) |
begin |
case (SSX_master) |
MASTERMX : SSX_AMSTR = MX; |
default : SSX_AMSTR = MASTER_NONE; |
endcase |
end |
ENDLOOP SX |
|
assign SSX_MMX = SSX_master[MX]; |
|
assign MMX_ABUS = {GONCAT(MMX_AGROUP_IC_AXI_A.IN ,)}; |
|
|
assign {GONCAT(SSX_AGROUP_IC_AXI_A.IN ,)} = SSX_ABUS; |
|
|
LOOP SX |
assign SSX_ABUS = CONCAT((MMX_ABUS & {ABUS_WIDTH{SSX_MMX}}) |); |
assign SSX_AIDOK = CONCAT((SSX_MMX & MMX_AIDOK) |); |
ENDLOOP SX |
|
LOOP MX |
assign MMX_AREADY = |
SSX_MMX ? SSX_AREADY : |
~MMX_AVALID; |
ENDLOOP MX |
|
endmodule |
|
|
|
/src/base/def_ic_static.txt
0,0 → 1,97
<##////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 //// |
//// //// |
//////////////////////////////////////////////////////////////////##> |
|
##Static defines |
SWAP MSTRS MASTER_NUM |
SWAP SLVS EXPR(SLAVE_NUM+DVAL(DEF_DECERR_SLV)) |
|
LOOP MX MSTRS |
LOOP SX SLVS |
|
SWAP MSTR_BITS LOG2(MSTRS) |
SWAP SLV_BITS LOG2(SLVS) |
|
SWAP SERR EXPR(SLVS-1) |
|
GROUP IC_AXI_A is { |
ID ID_BITS input |
ADDR ADDR_BITS input |
LEN 4 input |
SIZE 2 input |
BURST 2 input |
CACHE 4 input |
PROT 3 input |
LOCK 2 input |
USER USER_BITS input |
VALID 1 input |
READY 1 output |
} |
|
GROUP IC_AXI_W is { |
ID ID_BITS input |
DATA DATA_BITS input |
STRB DATA_BITS/8 input |
LAST 1 input |
USER USER_BITS input |
VALID 1 input |
READY 1 output |
} |
|
GROUP IC_AXI_B is { |
ID ID_BITS output |
RESP 2 output |
USER USER_BITS output |
VALID 1 output |
READY 1 input |
} |
|
GROUP IC_AXI_R is { |
ID ID_BITS output |
DATA DATA_BITS output |
RESP 2 output |
LAST 1 output |
USER USER_BITS output |
VALID 1 output |
READY 1 input |
} |
|
GROUP IC_AXI joins { |
GROUP IC_AXI_A prefix_AW |
GROUP IC_AXI_W prefix_W |
GROUP IC_AXI_B prefix_B |
GROUP IC_AXI_A prefix_AR |
GROUP IC_AXI_R prefix_R |
} |
|
GROUP IC_AXI_CMD is { |
SLV SLV_BITS input |
ID ID_BITS input |
VALID 1 input |
READY 1 input |
} |
/src/base/ic_registry_wr.v
0,0 → 1,166
<##////////////////////////////////////////////////////////////////// |
//// //// |
//// 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_ic_registry_wr.v |
|
ITER MX |
ITER SX |
|
LOOP MX |
ITER MMX_IDX |
ENDLOOP MX |
|
module PREFIX_ic_registry_wr(PORTS); |
|
|
|
input clk; |
input reset; |
|
port MMX_AWGROUP_IC_AXI_CMD; |
|
input [ID_BITS-1:0] MMX_WID; |
input MMX_WVALID; |
input MMX_WREADY; |
input MMX_WLAST; |
output [SLV_BITS-1:0] MMX_WSLV; |
output MMX_WOK; |
|
input SSX_AWVALID; |
input SSX_AWREADY; |
input [MSTR_BITS-1:0] SSX_AWMSTR; |
input SSX_WVALID; |
input SSX_WREADY; |
input SSX_WLAST; |
|
|
wire AWmatch_MMX_IDMMX_IDX; |
wire Wmatch_MMX_IDMMX_IDX; |
|
wire cmd_push_MMX; |
wire cmd_push_MMX_IDMMX_IDX; |
|
wire cmd_pop_MMX; |
wire cmd_pop_MMX_IDMMX_IDX; |
|
wire [SLV_BITS-1:0] slave_in_MMX_IDMMX_IDX; |
wire [SLV_BITS-1:0] slave_out_MMX_IDMMX_IDX; |
wire slave_empty_MMX_IDMMX_IDX; |
wire slave_full_MMX_IDMMX_IDX; |
|
wire cmd_push_SSX; |
wire cmd_pop_SSX; |
wire [MSTR_BITS-1:0] master_in_SSX; |
wire [MSTR_BITS-1:0] master_out_SSX; |
wire master_empty_SSX; |
wire master_full_SSX; |
|
reg [SLV_BITS-1:0] MMX_WSLV; |
reg MMX_WOK; |
|
|
|
|
assign AWmatch_MMX_IDMMX_IDX = MMX_AWID == ID_MMX_IDMMX_IDX; |
|
assign Wmatch_MMX_IDMMX_IDX = MMX_WID == ID_MMX_IDMMX_IDX; |
|
|
assign cmd_push_MMX = MMX_AWVALID & MMX_AWREADY; |
assign cmd_push_MMX_IDMMX_IDX = cmd_push_MMX & AWmatch_MMX_IDMMX_IDX; |
assign cmd_pop_MMX = MMX_WVALID & MMX_WREADY & MMX_WLAST; |
assign cmd_pop_MMX_IDMMX_IDX = cmd_pop_MMX & Wmatch_MMX_IDMMX_IDX; |
|
assign cmd_push_SSX = SSX_AWVALID & SSX_AWREADY; |
assign cmd_pop_SSX = SSX_WVALID & SSX_WREADY & SSX_WLAST; |
assign master_in_SSX = SSX_AWMSTR; |
|
assign slave_in_MMX_IDMMX_IDX = MMX_AWSLV; |
|
|
LOOP MX |
always @(MMX_WID |
or slave_out_MMX_IDMMX_IDX |
) |
begin |
case (MMX_WID) |
ID_MMX_IDMMX_IDX : MMX_WSLV = slave_out_MMX_IDMMX_IDX; |
default : MMX_WSLV = SERR; |
endcase |
end |
|
always @(MMX_WSLV |
or master_out_SSX |
) |
begin |
case (MMX_WSLV) |
'dSX : MMX_WOK = master_out_SSX == 'dMX; |
default : MMX_WOK = 1'b0; |
endcase |
end |
|
ENDLOOP MX |
|
LOOP MX |
LOOP MMX_IDX |
prgen_fifo #(SLV_BITS, CMD_DEPTH) |
slave_fifo_MMX_IDMMX_IDX( |
.clk(clk), |
.reset(reset), |
.push(cmd_push_MMX_IDMMX_IDX), |
.pop(cmd_pop_MMX_IDMMX_IDX), |
.din(slave_in_MMX_IDMMX_IDX), |
.dout(slave_out_MMX_IDMMX_IDX), |
.empty(slave_empty_MMX_IDMMX_IDX), |
.full(slave_full_MMX_IDMMX_IDX) |
); |
|
ENDLOOP MMX_IDX |
ENDLOOP MX |
|
|
|
LOOP SX |
prgen_fifo #(MSTR_BITS, 32) |
master_fifo_SSX( |
.clk(clk), |
.reset(reset), |
.push(cmd_push_SSX), |
.pop(cmd_pop_SSX), |
.din(master_in_SSX), |
.dout(master_out_SSX), |
.empty(master_empty_SSX), |
.full(master_full_SSX) |
); |
|
ENDLOOP SX |
|
endmodule |
|
|
/src/base/ic.v
0,0 → 1,143
<##////////////////////////////////////////////////////////////////// |
//// //// |
//// 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_ic.v |
INCLUDE def_ic.txt |
ITER MX |
|
ITER SX SLAVE_NUM ##external slave ports don't include decerr slave |
|
module PREFIX_ic (PORTS); |
|
input clk; |
input reset; |
|
port MMX_GROUP_IC_AXI; |
revport SSX_GROUP_IC_AXI; |
ENDITER SX |
ITER SX ##use global iterator |
|
wire [EXPR(SLV_BITS-1):0] MMX_AWSLV; |
wire [EXPR(SLV_BITS-1):0] MMX_ARSLV; |
|
wire [EXPR(MSTR_BITS-1):0] SSX_AWMSTR; |
wire [EXPR(MSTR_BITS-1):0] SSX_ARMSTR; |
wire SSX_AWIDOK; |
wire SSX_ARIDOK; |
|
|
CREATE ic_addr.v def_ic.txt |
PREFIX_ic_addr |
PREFIX_ic_addr_rd (.clk(clk), |
.reset(reset), |
.MMX_ASLV(MMX_ARSLV), |
.MMX_AGROUP_IC_AXI_A(MMX_ARGROUP_IC_AXI_A), |
.SSX_AMSTR(SSX_ARMSTR), |
.SSX_AIDOK(SSX_ARIDOK), |
.SSX_AGROUP_IC_AXI_A(SSX_ARGROUP_IC_AXI_A), |
STOMP , |
); |
|
|
PREFIX_ic_addr |
PREFIX_ic_addr_wr ( |
.clk(clk), |
.reset(reset), |
.MMX_ASLV(MMX_AWSLV), |
.MMX_AGROUP_IC_AXI_A(MMX_AWGROUP_IC_AXI_A), |
.SSX_AMSTR(SSX_AWMSTR), |
.SSX_AIDOK(SSX_AWIDOK), |
.SSX_AGROUP_IC_AXI_A(SSX_AWGROUP_IC_AXI_A), |
STOMP , |
); |
|
|
CREATE ic_resp.v def_ic.txt DEFCMD(SWAP CONST(RW) R) |
PREFIX_ic_resp |
PREFIX_ic_rresp ( |
.clk(clk), |
.reset(reset), |
.MMX_AGROUP_IC_AXI_CMD(MMX_ARGROUP_IC_AXI_CMD), |
.MMX_GROUP_IC_AXI_R(MMX_RGROUP_IC_AXI_R), |
.SSX_GROUP_IC_AXI_R(SSX_RGROUP_IC_AXI_R), |
STOMP , |
); |
|
|
CREATE ic_wdata.v def_ic.txt |
PREFIX_ic_wdata |
PREFIX_ic_wdata ( |
.clk(clk), |
.reset(reset), |
.MMX_AWGROUP_IC_AXI_CMD(MMX_AWGROUP_IC_AXI_CMD), |
.MMX_WGROUP_IC_AXI_W(MMX_WGROUP_IC_AXI_W), |
.SSX_WGROUP_IC_AXI_W(SSX_WGROUP_IC_AXI_W), |
.SSX_AWVALID(SSX_AWVALID), |
.SSX_AWREADY(SSX_AWREADY), |
.SSX_AWMSTR(SSX_AWMSTR), |
STOMP , |
); |
|
|
CREATE ic_resp.v def_ic.txt DEFCMD(SWAP CONST(RW) W) |
PREFIX_ic_resp |
PREFIX_ic_bresp ( |
.clk(clk), |
.reset(reset), |
.MMX_AGROUP_IC_AXI_CMD(MMX_AWGROUP_IC_AXI_CMD), |
.MMX_GROUP_IC_AXI_B(MMX_BGROUP_IC_AXI_B), |
.MMX_DATA(), |
.MMX_LAST(), |
.SSX_GROUP_IC_AXI_B(SSX_BGROUP_IC_AXI_B), |
.SSX_DATA({DATA_BITS{1'b0}}), |
.SSX_LAST(1'b1), |
STOMP , |
); |
|
|
IFDEF DEF_DECERR_SLV |
wire SSERR_GROUP_IC_AXI; |
|
CREATE ic_decerr.v def_ic.txt |
PREFIX_ic_decerr |
PREFIX_ic_decerr ( |
.clk(clk), |
.reset(reset), |
.AWIDOK(SSERR_AWIDOK), |
.ARIDOK(SSERR_ARIDOK), |
.GROUP_IC_AXI(SSERR_GROUP_IC_AXI), |
STOMP , |
); |
ENDIF DEF_DECERR_SLV |
|
|
endmodule |
|
|
|
/src/base/def_axi_master_static.txt
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 //// |
//// //// |
//////////////////////////////////////////////////////////////////##> |
|
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 { |
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}}) |
} |
|
/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 |
|
|
|
|
|
|
|
|
/src/base/axi_master.v
0,0 → 1,301
///////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.v |
|
INCLUDE def_axi_master.txt |
|
|
////////////////////////////////////// |
// |
// 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 |
// |
// 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 LEN (length) |
// len_max - maximum burst LEN (length) |
// size_min - minimum burst SIZE (length) |
// size_max - maximum burst SIZE (length) |
// addr_min - minimum address (in bytes) |
// addr_max - maximum address (in bytes) |
// |
////////////////////////////////////// |
|
|
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 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 |
|
|
/src/base/axi_master_single.v
0,0 → 1,832
///////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 = 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 = 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 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 |
|
|
/src/base/ic_arbiter.v
0,0 → 1,126
<##////////////////////////////////////////////////////////////////// |
//// //// |
//// 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_ic_MSTR_SLV_arbiter.v |
|
ITER MX MSTRNUM |
ITER SX SLVNUM |
|
module PREFIX_ic_MSTR_SLV_arbiter(PORTS); |
|
input clk; |
input reset; |
|
input [MSTRNUM-1:0] M_last; |
input [MSTRNUM-1:0] M_req; |
input [MSTRNUM-1:0] M_grant; |
|
input [LOG2(SLVNUM)-1:0] MMX_slave; |
|
output [MSTRNUM-1:0] SSX_master; |
|
|
|
reg [MSTRNUM:0] SSX_master_prio_reg; |
wire [MSTRNUM-1:0] SSX_master_prio; |
reg [MSTRNUM-1:0] SSX_master_d; |
|
wire [MSTRNUM-1:0] M_SSX; |
wire [MSTRNUM-1:0] M_SSX_valid; |
wire [MSTRNUM-1:0] M_SSX_prio; |
reg [MSTRNUM-1:0] M_SSX_burst; |
|
|
|
|
parameter MASTER_NONE = BIN(0 MSTRNUM); |
parameter MASTERMX = BIN(EXPR(2^MX) MSTRNUM); |
|
|
|
|
IFDEF DEF_PRIO |
always @(posedge clk or posedge reset) |
if (reset) |
begin |
SSX_master_prio_reg[MSTRNUM:1] <= #FFD {MSTRNUM{1'b0}}; |
SSX_master_prio_reg[0] <= #FFD 1'b1; |
end |
else if (|(M_req & M_grant & M_last)) |
begin |
SSX_master_prio_reg[MSTRNUM:1] <= #FFD SSX_master_prio_reg[MSTRNUM-1:0]; |
SSX_master_prio_reg[0] <= #FFD SSX_master_prio_reg[MSTRNUM-1]; |
end |
|
assign SSX_master_prio = SSX_master_prio_reg[MSTRNUM-1:0]; |
|
assign M_SSX_prio = M_SSX_valid & SSX_master_prio; |
ENDIF DEF_PRIO |
|
|
|
always @(posedge clk or posedge reset) |
if (reset) |
begin |
SSX_master_d <= #FFD {MSTRNUM{1'b0}}; |
end |
else |
begin |
SSX_master_d <= #FFD SSX_master; |
end |
|
LOOP MX MSTRNUM |
always @(posedge clk or posedge reset) |
if (reset) |
begin |
M_SSX_burst[MX] <= #FFD 1'b0; |
end |
else if (M_req[MX]) |
begin |
M_SSX_burst[MX] <= #FFD SSX_master[MX] & (M_grant[MX] ? (~M_last[MX]) : 1'b1); |
end |
|
ENDLOOP MX |
|
assign M_SSX = {CONCAT(MMX_slave == 'dSX ,)}; |
|
assign M_SSX_valid = M_SSX & M_req; |
|
|
LOOP SX SLVNUM |
assign SSX_master = |
M_SSX_burst[MX] ? SSX_master_d : |
IF DEF_PRIO M_SSX_prio[MX] ? MASTERMX : |
M_SSX_valid[MX] ? MASTERMX : |
MASTER_NONE; |
|
ENDLOOP SX |
|
endmodule |
|
/src/base/ic_dec.v
0,0 → 1,74
<##////////////////////////////////////////////////////////////////// |
//// //// |
//// 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_ic_dec.v |
|
ITER MX |
ITER SX |
|
LOOP MX |
ITER MMX_IDX |
ENDLOOP MX |
|
module PREFIX_ic_dec (PORTS); |
|
input [ADDR_BITS-1:0] MMX_AADDR; |
input [ID_BITS-1:0] MMX_AID; |
output [SLV_BITS-1:0] MMX_ASLV; |
output MMX_AIDOK; |
|
parameter DEC_MSB = ADDR_BITS - 1; |
parameter DEC_LSB = ADDR_BITS - SLV_BITS; |
|
reg [SLV_BITS-1:0] MMX_ASLV; |
reg MMX_AIDOK; |
|
LOOP MX |
always @(MMX_AADDR or MMX_AIDOK) |
begin |
case ({MMX_AIDOK, MMX_AADDR[DEC_MSB:DEC_LSB]}) |
{1'b1, BIN(SX SLV_BITS)} : MMX_ASLV = 'dSX; |
default : MMX_ASLV = 'dSERR; |
endcase |
end |
|
always @(MMX_AID) |
begin |
case (MMX_AID) |
ID_MMX_IDMMX_IDX : MMX_AIDOK = 1'b1; |
default : MMX_AIDOK = 1'b0; |
endcase |
end |
|
ENDLOOP MX |
|
endmodule |
|
|
|
/README.txt
0,0 → 1,23
|
------------------------------ 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 AXI master stub |
|
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 axi_master.v, it calls the top definition file named def_axi_master.txt. |
|
The default definition file def_axi_master.txt generates an AXI master with 3 internal masters (AXI IDs), 64 bit data bus and command depth of 4. |
|
Changing the stub parameters should be made only in def_axi_master.txt in the src/base directory (changing ID number, ID values, data width etc.). |
|
Once the Verilog files have been generated instruction on how to use the stub are at the top of axi_master.v (tasks and parameters). |
|
|