URL
https://opencores.org/ocsvn/ahb_master/ahb_master/trunk
Subversion Repositories ahb_master
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/ahb_master/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 |
|
|
/ahb_master/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 |
|
/ahb_master/trunk/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 |
|
|
|
/ahb_master/trunk/src/base/ic_registry_resp.v
0,0 → 1,164
<##////////////////////////////////////////////////////////////////// |
//// //// |
//// 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_SSX_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_SSX_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 & match_SSX_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 |
|
|
/ahb_master/trunk/src/base/def_axi2ahb_static.txt
0,0 → 1,57
|
VERIFY ((DATA_BITS==32) || (DATA_BITS==64)) |
|
GROUP AXI_A is { |
ID ID_BITS input |
ADDR ADDR_BITS input |
LEN 4 input |
SIZE 2 input |
VALID 1 input |
READY 1 output |
} |
|
GROUP AXI_W is { |
ID ID_BITS input |
DATA DATA_BITS input |
STRB DATA_BITS/8 input |
LAST 1 input |
VALID 1 input |
READY 1 output |
} |
|
GROUP AXI_B is { |
ID ID_BITS output |
RESP 2 output |
VALID 1 output |
READY 1 input |
} |
|
GROUP AXI_R is { |
ID ID_BITS output |
DATA DATA_BITS output |
RESP 2 output |
LAST 1 output |
VALID 1 output |
READY 1 input |
} |
|
GROUP AXI joins { |
GROUP AXI_A prefix_AW |
GROUP AXI_W prefix_W |
GROUP AXI_B prefix_B |
GROUP AXI_A prefix_AR |
GROUP AXI_R prefix_R |
} |
|
|
GROUP AHB is { |
HADDR ADDR_BITS input |
HBURST 3 input |
HSIZE 2 input |
HTRANS 2 input |
HWRITE 1 input |
HWDATA DATA_BITS input |
HRDATA DATA_BITS output |
HREADY 1 output |
HRESP 1 output |
} |
/ahb_master/trunk/src/base/axi2ahb.v
0,0 → 1,121
|
INCLUDE def_axi2ahb.txt |
OUTFILE PREFIX_axi2ahb.v |
|
CHECK CONST(#FFD) |
CHECK CONST(PREFIX) |
CHECK CONST(ADDR_BITS) |
CHECK CONST(DATA_BITS) |
CHECK CONST(ID_BITS) |
CHECK CONST(CMD_DEPTH) |
|
module PREFIX_axi2ahb (PORTS); |
|
input clk; |
input reset; |
|
port GROUP_AXI; |
|
revport GROUP_AHB; |
|
|
//outputs of cmd |
wire cmd_empty; |
wire cmd_read; |
wire [ID_BITS-1:0] cmd_id; |
wire [ADDR_BITS-1:0] cmd_addr; |
wire [3:0] cmd_len; |
wire [1:0] cmd_size; |
wire cmd_err; |
|
//outputs of ctrl |
wire ahb_finish; |
wire data_last; |
|
//outputs of wr fifo |
wire wdata_phase; |
wire wdata_ready; |
|
//outputs of rd fifo |
wire rdata_phase; |
wire rdata_ready; |
|
|
|
CREATE axi2ahb_cmd.v |
PREFIX_axi2ahb_cmd PREFIX_axi2ahb_cmd( |
.clk(clk), |
.reset(reset), |
.AWGROUP_AXI_A(AWGROUP_AXI_A), |
.ARGROUP_AXI_A(ARGROUP_AXI_A), |
.GROUP_AHB(GROUP_AHB), |
.ahb_finish(ahb_finish), |
.cmd_empty(cmd_empty), |
.cmd_read(cmd_read), |
.cmd_id(cmd_id), |
.cmd_addr(cmd_addr), |
.cmd_len(cmd_len), |
.cmd_size(cmd_size), |
.cmd_err(cmd_err) |
); |
|
|
|
CREATE axi2ahb_ctrl.v |
PREFIX_axi2ahb_ctrl PREFIX_axi2ahb_ctrl( |
.clk(clk), |
.reset(reset), |
.GROUP_AHB(GROUP_AHB), |
.ahb_finish(ahb_finish), |
.rdata_phase(rdata_phase), |
.wdata_phase(wdata_phase), |
.data_last(data_last), |
.rdata_ready(rdata_ready), |
.wdata_ready(wdata_ready), |
.cmd_empty(cmd_empty), |
.cmd_read(cmd_read), |
.cmd_addr(cmd_addr), |
.cmd_len(cmd_len), |
.cmd_size(cmd_size) |
); |
|
|
CREATE axi2ahb_wr_fifo.v |
PREFIX_axi2ahb_wr_fifo |
PREFIX_axi2ahb_wr_fifo( |
.clk(clk), |
.reset(reset), |
.WGROUP_AXI_W(WGROUP_AXI_W), |
.BGROUP_AXI_B(BGROUP_AXI_B), |
.HWDATA(HWDATA), |
.HREADY(HREADY), |
.HTRANS(HTRANS), |
.HRESP(HRESP), |
.cmd_err(cmd_err), |
.wdata_phase(wdata_phase), |
.wdata_ready(wdata_ready), |
.data_last(data_last) |
); |
|
|
CREATE axi2ahb_rd_fifo.v |
PREFIX_axi2ahb_rd_fifo |
PREFIX_axi2ahb_rd_fifo( |
.clk(clk), |
.reset(reset), |
.RGROUP_AXI_R(RGROUP_AXI_R), |
.HRDATA(HRDATA), |
.HREADY(HREADY), |
.HTRANS(HTRANS), |
.HRESP(HRESP), |
.cmd_id(cmd_id), |
.cmd_err(cmd_err), |
.rdata_phase(rdata_phase), |
.rdata_ready(rdata_ready), |
.data_last(data_last) |
); |
|
|
endmodule |
|
|
/ahb_master/trunk/src/base/ic_decerr.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_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; |
|
|
IFDEF TRUE (USER_BITS>0) |
assign BUSER = 'd0; |
assign RUSER = 'd0; |
ENDIF TRUE (USER_BITS>0) |
|
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 |
|
|
/ahb_master/trunk/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 |
/ahb_master/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 |
|
/ahb_master/trunk/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 |
|
|
|
/ahb_master/trunk/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 |
|
|
|
/ahb_master/trunk/src/base/def_axi_master_rand.txt
0,0 → 1,12
|
GROUP AXI_MASTER_RAND is { |
ahb_bursts SON(DEFAULT 0) |
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}}) |
} |
|
/ahb_master/trunk/src/base/axi2ahb_wr_fifo.v
0,0 → 1,108
|
INCLUDE def_axi2ahb.txt |
OUTFILE PREFIX_axi2ahb_wr_fifo.v |
|
module PREFIX_axi2ahb_wr_fifo (PORTS); |
|
parameter FIFO_LINES = EXPR(2 * 16); //double buffer of max burst |
parameter RESP_SLVERR = 2'b10; |
|
input clk; |
input reset; |
|
port WGROUP_AXI_W; |
port BGROUP_AXI_B; |
output [DATA_BITS-1:0] HWDATA; |
input HREADY; |
input [1:0] HTRANS; |
input HRESP; |
|
input cmd_err; |
input wdata_phase; |
output wdata_ready; |
input data_last; |
|
|
wire data_push; |
wire data_pop; |
wire data_empty; |
wire data_full; |
|
wire resp_push; |
wire resp_pop; |
wire resp_empty; |
wire resp_full; |
|
reg [LOG2(CMD_DEPTH):0] burst_cnt; |
wire burst_full; |
|
wire axi_last; |
wire ahb_last; |
wire [1:0] cmd_resp; |
|
assign cmd_resp = cmd_err | HRESP ? RESP_SLVERR : 2'b00; |
|
assign wdata_ready = burst_cnt > 'd0; |
|
assign WREADY = (~data_full) & (~burst_full); |
|
|
assign data_push = WVALID & WREADY; |
assign data_pop = wdata_phase & HREADY; |
|
assign axi_last = WVALID & WREADY & WLAST; |
assign ahb_last = wdata_phase & data_last; |
|
assign burst_full = burst_cnt == {EXPR(LOG2(CMD_DEPTH)+1){1'b1}}; |
|
always @(posedge clk or posedge reset) |
if (reset) |
burst_cnt <= #FFD 'd0; |
else if (axi_last | ahb_last) |
burst_cnt <= #FFD burst_cnt + axi_last - ahb_last; |
|
prgen_fifo #(DATA_BITS, FIFO_LINES) |
data_fifo( |
.clk(clk), |
.reset(reset), |
.push(data_push), |
.pop(data_pop), |
.din({WDATA |
} |
), |
.dout({HWDATA |
} |
), |
.empty(data_empty), |
.full(data_full) |
); |
|
|
assign resp_push = ahb_last; |
assign resp_pop = BVALID & BREADY; |
|
assign BVALID = (~resp_empty); |
|
prgen_fifo #(2+ID_BITS, CMD_DEPTH) |
resp_fifo( |
.clk(clk), |
.reset(reset), |
.push(resp_push), |
.pop(resp_pop), |
.din({cmd_resp, |
WID |
} |
), |
.dout({BRESP, |
BID |
} |
), |
.empty(resp_empty), |
.full(resp_full) |
); |
|
|
|
endmodule |
|
|
/ahb_master/trunk/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 |
} |
/ahb_master/trunk/src/base/def_axi_master_static.txt
0,0 → 1,79
<##////////////////////////////////////////////////////////////////// |
//// //// |
//// 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_rand.txt |
|
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 |
} |
/ahb_master/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 |
|
|
|
|
|
|
|
|
/ahb_master/trunk/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 |
|
|
|
/ahb_master/trunk/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 |
|
|
/ahb_master/trunk/src/base/axi_master.v
0,0 → 1,367
///////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 |
// |
// insert_rand(input burst_num) |
// Description: disperces burst_num between internal masters and calls insert_rand_chk for each master |
// Parameters: burst_num - total number of bursts to check (combined) |
// |
// |
// Parameters: |
// |
// For random testing: (changing these values automatically update interanl masters) |
// ahb_bursts - if set, bursts will only be of length 1, 4, 8 or 16. |
// 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); |
|
`include "prgen_rand.v" |
|
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 SLAVE_NUM 1) \\ |
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) \\ |
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 |
|
task insert_rand; |
input [31:0] burst_num; |
|
ITER IDX ID_NUM |
reg [31:0] burst_numIDX; |
integer remain; |
begin |
remain = burst_num; |
LOOP IDX ID_NUM |
if (remain > 0) |
begin |
burst_numIDX = rand(1, remain); |
remain = remain - burst_numIDX; |
insert_rand_chk(IDX, burst_numIDX); |
end |
ENDLOOP IDX |
end |
endtask |
|
|
endmodule |
|
|
/ahb_master/trunk/src/base/def_ahb_master.txt
0,0 → 1,13
|
INCLUDE def_axi_master_rand.txt |
INCLUDE def_axi2ahb.txt |
|
SWAP.GLOBAL #FFD #1 ## flip-flop delay |
|
SWAP PREFIX ahb_master ## prefix for all modules and file names |
|
SWAP ADDR_BITS 24 ## AXI and AHB address bits |
SWAP DATA_BITS 32 ## AXI and AHB data bits |
|
SWAP SIZE_BITS 2 |
|
/ahb_master/trunk/src/base/axi_master_single.v
0,0 → 1,868
///////////////////////////////////////////////////////////////////// |
//// //// |
//// 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 |
|
#FFD; 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 |
|
#FFD; 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; |
|
#FFD; 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; |
|
#FFD; 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 |
if (DATA_BITS==32) size_max = 2'b10; |
len = rand(len_min, len_max); |
size = rand(size_min, size_max); |
addr = rand_align(addr_min, addr_max, 1 << size); |
|
if (ahb_bursts) |
begin |
len = |
len[3] ? 15 : |
len[2] ? 7 : |
len[1] ? 3 : 0; |
if (len > 0) |
size = (DATA_BITS == 64) ? 2'b11 : 2'b10; //AHB bursts always full data |
|
addr = align(addr, EXPR(DATA_BITS/8)*(len+1)); //address aligned to burst size |
end |
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 |
#FFD; 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 |
#FFD; 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 |
#FFD; 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 |
|
|
/ahb_master/trunk/src/base/axi2ahb_cmd.v
0,0 → 1,105
|
OUTFILE PREFIX_axi2ahb_cmd.v |
|
INCLUDE def_axi2ahb.txt |
|
module PREFIX_axi2ahb_cmd (PORTS); |
|
input clk; |
input reset; |
|
port AWGROUP_AXI_A; |
port ARGROUP_AXI_A; |
input GROUP_AHB; |
|
input ahb_finish; |
output cmd_empty; |
output cmd_read; |
output [ID_BITS-1:0] cmd_id; |
output [ADDR_BITS-1:0] cmd_addr; |
output [3:0] cmd_len; |
output [1:0] cmd_size; |
output cmd_err; |
|
|
wire AGROUP_AXI_A; |
|
wire cmd_push; |
wire cmd_pop; |
wire cmd_empty; |
wire cmd_full; |
reg read; |
wire err; |
|
|
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_AXI_A = read ? ARGROUP_AXI_A : AWGROUP_AXI_A; |
|
assign ARREADY = (~cmd_full) & read; |
assign AWREADY = (~cmd_full) & (~read); |
|
assign err = |
((ALEN != 4'd0) & |
(ALEN != 4'd3) & |
(ALEN != 4'd7) & |
(ALEN != 4'd15)) | |
(((ASIZE == 2'b01) & (AADDR[0] != 1'b0)) | |
((ASIZE == 2'b10) & (AADDR[1:0] != 2'b00)) | |
((ASIZE == 2'b11) & (AADDR[2:0] != 3'b000))); |
|
|
|
assign cmd_push = AVALID & AREADY; |
assign cmd_pop = ahb_finish; |
|
CREATE prgen_fifo.v DEFCMD(SWAP CONST(#FFD) #FFD) |
prgen_fifo #(ID_BITS+ADDR_BITS+4+2+1+1, CMD_DEPTH) |
cmd_fifo( |
.clk(clk), |
.reset(reset), |
.push(cmd_push), |
.pop(cmd_pop), |
.din({ |
AID, |
AADDR, |
ALEN, |
ASIZE, |
read, |
err |
} |
), |
.dout({ |
cmd_id, |
cmd_addr, |
cmd_len, |
cmd_size, |
cmd_read, |
cmd_err |
} |
), |
.empty(cmd_empty), |
.full(cmd_full) |
); |
|
|
|
endmodule |
|
|
/ahb_master/trunk/src/base/axi2ahb_ctrl.v
0,0 → 1,142
|
INCLUDE def_axi2ahb.txt |
OUTFILE PREFIX_axi2ahb_ctrl.v |
|
module PREFIX_axi2ahb_ctrl (PORTS); |
|
|
input clk; |
input reset; |
|
revport GROUP_AHB; |
|
output ahb_finish; |
output rdata_phase; |
output wdata_phase; |
output data_last; |
|
input rdata_ready; |
input wdata_ready; |
input cmd_empty; |
input cmd_read; |
input [ADDR_BITS-1:0] cmd_addr; |
input [3:0] cmd_len; |
input [1:0] cmd_size; |
|
parameter TRANS_IDLE = 2'b00; |
parameter TRANS_BUSY = 2'b01; |
parameter TRANS_NONSEQ = 2'b10; |
parameter TRANS_SEQ = 2'b11; |
|
parameter BURST_SINGLE = 3'b000; |
parameter BURST_INCR4 = 3'b011; |
parameter BURST_INCR8 = 3'b101; |
parameter BURST_INCR16 = 3'b111; |
|
|
wire data_ready; |
wire ahb_idle; |
wire ahb_ack; |
wire ahb_ack_last; |
wire ahb_start; |
wire ahb_last; |
wire data_last; |
reg [4:0] cmd_counter; |
reg rdata_phase; |
reg wdata_phase; |
reg [1:0] HTRANS; |
reg [2:0] HBURST; |
reg [1:0] HSIZE; |
reg HWRITE; |
reg [ADDR_BITS-1:0] HADDR; |
|
|
assign ahb_finish = ahb_ack_last; |
|
assign data_ready = cmd_read ? rdata_ready : wdata_ready; |
|
assign ahb_idle = HTRANS == TRANS_IDLE; |
assign ahb_ack = HTRANS[1] & HREADY; |
assign ahb_ack_last = ahb_last & ahb_ack; |
assign ahb_start = (~cmd_empty) & data_ready & ahb_idle; |
assign data_last = HREADY & (ahb_idle || (HTRANS == TRANS_NONSEQ)); |
|
always @(posedge clk or posedge reset) |
if (reset) |
cmd_counter <= #FFD 4'd0; |
else if (ahb_ack_last) |
cmd_counter <= #FFD 4'd0; |
else if (ahb_ack) |
cmd_counter <= #FFD cmd_counter + 1'b1; |
|
assign ahb_last = cmd_counter == cmd_len; |
|
always @(posedge clk or posedge reset) |
if (reset) |
rdata_phase <= #FFD 1'b0; |
else if (ahb_ack & (~HWRITE)) |
rdata_phase <= #FFD 1'b1; |
else if (data_last) |
rdata_phase <= #FFD 1'b0; |
|
always @(posedge clk or posedge reset) |
if (reset) |
wdata_phase <= #FFD 1'b0; |
else if (ahb_ack & HWRITE) |
wdata_phase <= #FFD 1'b1; |
else if (data_last) |
wdata_phase <= #FFD 1'b0; |
|
always @(posedge clk or posedge reset) |
if (reset) |
HTRANS <= #FFD TRANS_IDLE; |
else if (ahb_start) |
HTRANS <= #FFD TRANS_NONSEQ; |
else if (ahb_ack_last) |
HTRANS <= #FFD TRANS_IDLE; |
else if (ahb_ack) |
HTRANS <= #FFD TRANS_SEQ; |
|
always @(posedge clk or posedge reset) |
if (reset) |
HBURST <= #FFD BURST_SINGLE; |
else if (ahb_start & (cmd_len == 4'd0)) |
HBURST <= #FFD BURST_SINGLE; |
else if (ahb_start & (cmd_len == 4'd3)) |
HBURST <= #FFD BURST_INCR4; |
else if (ahb_start & (cmd_len == 4'd7)) |
HBURST <= #FFD BURST_INCR8; |
else if (ahb_start & (cmd_len == 4'd15)) |
HBURST <= #FFD BURST_INCR16; |
|
always @(posedge clk or posedge reset) |
if (reset) |
HSIZE <= #FFD 2'b00; |
else if (ahb_start) |
HSIZE <= cmd_size; |
|
always @(posedge clk or posedge reset) |
if (reset) |
HWRITE <= #FFD 2'b00; |
else if (ahb_start) |
HWRITE <= (~cmd_read); |
|
always @(posedge clk or posedge reset) |
if (reset) |
HADDR <= #FFD {ADDR_BITS{1'b0}}; |
else if (ahb_start) |
HADDR <= #FFD cmd_addr; |
else if (ahb_ack_last) |
HADDR <= #FFD {ADDR_BITS{1'b0}}; |
else if (ahb_ack) |
HADDR <= #FFD HADDR + ( |
HSIZE == 2'b00 ? 4'd1 : |
HSIZE == 2'b01 ? 4'd2 : |
HSIZE == 2'b10 ? 4'd4 : |
HSIZE == 2'b11 ? 4'd8 : |
4'd0); |
|
|
endmodule |
|
|
/ahb_master/trunk/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 |
|
/ahb_master/trunk/src/base/ahb_master.v
0,0 → 1,234
|
////////////////////////////////////// |
// |
// General: |
// The AHB is built of an AXI master and an AXI2AHB bridge |
// |
// |
// I/F : |
// idle - all internal masters emptied their command FIFOs |
// scrbrd_empty - all scoreboard checks have been completed (for random testing) |
// |
// |
// Tasks: |
// |
// enable() |
// Description: Enables AHB master |
// |
// write_single(input addr, input wdata) |
// Description: write a single AHB burst (1 data cycle) |
// Parameters: |
// addr - address |
// wdata - write data |
// |
// read_single(input addr, output rdata) |
// Description: |
// Parameters: |
// addr - address |
// rdata - return read data |
// |
// check_single(input addr, input expected) |
// Description: read a single AHB burst and gives an error if the data read does not match expected |
// Parameters: |
// addr - address |
// expected - expected read data |
// |
// write_and_check_single(input addr, input data) |
// Description: write a single AHB burst read it back and compare the write and read data |
// Parameters: |
// addr - address |
// data - data to write and expect on read |
// |
// insert_wr_cmd(input addr, input len, input size) |
// Description: add an AHB write burst to command FIFO |
// Parameters: |
// addr - address |
// len - AHB LEN (data strobe number) |
// size - AHB SIZE (data width) |
// |
// insert_rd_cmd(input addr, input len, input size) |
// Description: add an AHB read burst to command FIFO |
// Parameters: |
// addr - address |
// len - AHB LEN (data strobe number) |
// size - AHB SIZE (data width) |
// |
// insert_wr_data(input wdata) |
// Description: add a single data to data FIFO (to be used in write bursts) |
// Parameters: |
// wdata - write data |
// |
// insert_wr_incr_data(input addr, input len, input size) |
// Description: add an AHB write burst to command FIFO will use incremental data (no need to use insert_wr_data) |
// Parameters: |
// addr - address |
// len - AHB LEN (data strobe number) |
// size - AHB SIZE (data width) |
// |
// insert_rand_chk(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: |
// burst_num - total number of bursts to check |
// |
// |
// Parameters: |
// |
// For random testing: (changing these values automatically update interanl masters) |
// len_min - minimum burst AHB LEN (length) |
// len_max - maximum burst AHB LEN (length) |
// size_min - minimum burst AHB SIZE (width) |
// size_max - maximum burst AHB SIZE (width) |
// addr_min - minimum address (in bytes) |
// addr_max - maximum address (in bytes) |
// |
////////////////////////////////////// |
|
OUTFILE PREFIX.v |
|
INCLUDE def_ahb_master.txt |
|
module PREFIX(PORTS); |
input clk; |
input reset; |
|
revport GROUP_AHB; |
output idle; |
output scrbrd_empty; |
|
|
parameter LEN_BITS = 4; |
##parameter SIZE_BITS = 2; |
|
wire GROUP_AXI; |
|
wire GROUP_AHB; |
|
integer GROUP_AXI_MASTER_RAND = GROUP_AXI_MASTER_RAND.DEFAULT; |
|
always @(*) |
begin |
#FFD; |
axi_master.GROUP_AXI_MASTER_RAND = GROUP_AXI_MASTER_RAND; |
end |
|
initial |
begin |
#100; |
axi_master.ahb_bursts=1; |
end |
|
|
CREATE axi_master.v \\ |
DEFCMD(SWAP.GLOBAL CONST(ID_BITS) ID_BITS) \\ |
DEFCMD(SWAP.GLOBAL CONST(ADDR_BITS) ADDR_BITS) \\ |
DEFCMD(SWAP.GLOBAL CONST(DATA_BITS) DATA_BITS) \\ |
DEFCMD(SWAP.GLOBAL CONST(ID_NUM) 1) \\ |
DEFCMD(SWAP.GLOBAL CONST(ID0_VAL) ID_BITS'b0) |
axi_master axi_master( |
.clk(clk), |
.reset(reset), |
|
.GROUP_AXI(GROUP_AXI), |
.idle(idle), |
.scrbrd_empty(scrbrd_empty) |
); |
|
|
CREATE axi2ahb.v \\ |
DEFCMD(SWAP.GLOBAL CONST(PREFIX) ahbm) \\ |
DEFCMD(SWAP.GLOBAL CONST(CMD_DEPTH) 4) \\ |
DEFCMD(SWAP.GLOBAL CONST(ADDR_BITS) ADDR_BITS) \\ |
DEFCMD(SWAP.GLOBAL CONST(DATA_BITS) DATA_BITS) \\ |
DEFCMD(SWAP.GLOBAL CONST(ID_BITS) ID_BITS) |
ahbm_axi2ahb ahbm_axi2ahb( |
.clk(clk), |
.reset(reset), |
|
.GROUP_AXI(GROUP_AXI), |
.GROUP_AHB(GROUP_AHB), |
STOMP , |
); |
|
task enable; |
begin |
axi_master.enable(0); |
end |
endtask |
|
task write_single; |
input [ADDR_BITS-1:0] addr; |
input [DATA_BITS-1:0] wdata; |
begin |
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 |
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 |
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 |
axi_master.write_and_check_single(0, addr, data); |
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 |
axi_master.insert_wr_cmd(0, addr, len, size); |
end |
endtask |
|
task insert_rd_cmd; |
input [ADDR_BITS-1:0] addr; |
input [LEN_BITS-1:0] len; |
input [SIZE_BITS-1:0] size; |
begin |
axi_master.insert_rd_cmd(0, addr, len, size); |
end |
endtask |
|
task insert_wr_data; |
input [DATA_BITS-1:0] wdata; |
begin |
axi_master.insert_wr_data(0, wdata); |
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; |
begin |
axi_master.insert_wr_incr_data(0, addr, len, size); |
end |
endtask |
|
task insert_rand_chk; |
input [31:0] burst_num; |
begin |
axi_master.insert_rand_chk(0, burst_num); |
end |
endtask |
|
|
endmodule |
|
|
/ahb_master/trunk/src/base/def_axi2ahb.txt
0,0 → 1,12
|
INCLUDE def_axi2ahb_static.txt |
|
SWAP #FFD #1 ## flip-flop delay |
|
SWAP PREFIX soc ## prefix for all modules and file names |
|
SWAP CMD_DEPTH 4 ## number of AXI command FIFO |
|
SWAP ADDR_BITS 24 ## AXI and AHB address bits |
SWAP DATA_BITS 32 ## AXI and AHB data bits |
SWAP ID_BITS 4 ## AXI ID bits |
/ahb_master/trunk/src/base/axi2ahb_rd_fifo.v
0,0 → 1,92
|
INCLUDE def_axi2ahb.txt |
OUTFILE PREFIX_axi2ahb_rd_fifo.v |
|
module PREFIX_axi2ahb_rd_fifo (PORTS); |
|
parameter FIFO_LINES = EXPR(2 * 16); //double buffer of max burst |
parameter RESP_SLVERR = 2'b10; |
|
input clk; |
input reset; |
|
port RGROUP_AXI_R; |
input [DATA_BITS-1:0] HRDATA; |
input HREADY; |
input [1:0] HTRANS; |
input HRESP; |
|
input [ID_BITS-1:0] cmd_id; |
input cmd_err; |
input rdata_phase; |
output rdata_ready; |
input data_last; |
|
|
wire data_push; |
wire data_pop; |
wire data_empty; |
wire data_full; |
|
reg RVALID; |
|
reg [LOG2(CMD_DEPTH):0] burst_cnt; |
|
wire axi_last; |
wire ahb_last; |
wire [1:0] cmd_resp; |
|
|
assign cmd_resp = cmd_err | HRESP ? RESP_SLVERR : 2'b00; |
|
assign rdata_ready = burst_cnt < 'd2; |
|
assign data_push = rdata_phase & HREADY; |
assign data_pop = RVALID & RREADY; |
|
assign axi_last = RVALID & RREADY & RLAST; |
assign ahb_last = rdata_phase & data_last; |
|
always @(posedge clk or posedge reset) |
if (reset) |
burst_cnt <= #FFD 'd0; |
else if (axi_last | ahb_last) |
burst_cnt <= #FFD burst_cnt - axi_last + ahb_last; |
|
prgen_fifo #(DATA_BITS+ID_BITS+2+1, FIFO_LINES) |
data_fifo( |
.clk(clk), |
.reset(reset), |
.push(data_push), |
.pop(data_pop), |
.din({HRDATA, |
cmd_id, |
cmd_resp, |
ahb_last |
} |
), |
.dout({RDATA, |
RID, |
RRESP, |
RLAST |
} |
), |
.empty(data_empty), |
.full(data_full) |
); |
|
|
always @(posedge clk or posedge reset) |
if (reset) |
RVALID <= #FFD 1'b0; |
else if (axi_last) |
RVALID <= #FFD 1'b0; |
else if (burst_cnt > 'd0) |
RVALID <= #FFD 1'b1; |
else |
RVALID <= #FFD 1'b0; |
|
|
endmodule |
|
|
/ahb_master/trunk/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 |
|
|
|
/ahb_master/trunk/README.txt
0,0 → 1,27
|
------------------------------ 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 AHB master stub |
|
The AHB master is built out of an AXI master and an AXI2AHB bridge. |
|
Supports 32 and 64 bits data bus. |
|
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 ahb_master.v, it calls the top definition file named def_ahb_master.txt. |
|
The default definition file def_ahb_master.txt generates an AHB master with a 32 bit data bus. |
|
Changing the stub parameters should be made only in def_ahb_master.txt in the src/base directory (changing address width, data width etc.). |
|
Once the Verilog files have been generated instruction on how to use the stub are at the top of ahb_master.v (tasks and parameters). |
|
|