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

Subversion Repositories robust_axi2apb

Compare Revisions

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

Rev 1 → Rev 2

/run/run.sh
0,0 → 1,9
#!/bin/bash
 
echo Starting RobustVerilog axi2apb run
rm -rf out
mkdir out
 
../../../robust ../src/base/axi2apb.v -od out -I ../src/gen -list apblist.txt -listpath -header
 
echo Completed RobustVerilog axi2apb run - results in run/out/
/src/gen/prgen_fifo.v
0,0 → 1,121
 
OUTFILE prgen_fifo.v
 
ITER DX 1 15
module prgen_fifo(PORTS);
 
parameter WIDTH = 8;
parameter DEPTH_FULL = 8;
 
parameter SINGLE = DEPTH_FULL == 1;
parameter DEPTH = SINGLE ? 1 : DEPTH_FULL -1;
parameter DEPTH_BITS =
(DEPTH <= EXPR(2^DX)) ? DX :
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;
output empty;
output full;
 
wire reg_push;
wire reg_pop;
wire fifo_push;
wire fifo_pop;
reg [DEPTH-1:0] fullness_in;
reg [DEPTH-1:0] fullness_out;
reg [DEPTH-1:0] fullness;
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 @(*)
begin
fullness_in = {DEPTH{1'b0}};
fullness_in[ptr_in] = fifo_push;
end
always @(*)
begin
fullness_out = {DEPTH{1'b0}};
fullness_out[ptr_out] = fifo_pop;
end
always @(posedge clk or posedge reset)
if (reset)
fullness <= #FFD {DEPTH{1'b0}};
else if (fifo_push | fifo_pop)
fullness <= #FFD (fullness & (~fullness_out)) | fullness_in;
 
 
assign next = |fullness;
assign fifo_empty = ~next;
assign empty = fifo_empty & dout_empty;
assign full = SINGLE ? !dout_empty : &fullness;
 
endmodule
 
 
/src/base/axi2apb_rd.v
0,0 → 1,47
INCLUDE def_axi2apb.txt
OUTFILE PREFIX_axi2apb_rd.v
 
module PREFIX_axi2apb_rd (PORTS);
 
input clk;
input reset;
 
input GROUP_APB3;
input cmd_err;
input [ID_BITS-1:0] cmd_id;
output finish_rd;
port RGROUP_APB_AXI_R;
parameter RESP_OK = 2'b00;
parameter RESP_SLVERR = 2'b10;
parameter RESP_DECERR = 2'b11;
reg RGROUP_APB_AXI_R.OUT;
assign finish_rd = RVALID & RREADY & RLAST;
always @(posedge clk or posedge reset)
if (reset)
begin
RGROUP_APB_AXI_R.OUT <= #FFD {GROUP_APB_AXI_R.OUT.WIDTH{1'b0}};
end
else if (finish_rd)
begin
RGROUP_APB_AXI_R.OUT <= #FFD {GROUP_APB_AXI_R.OUT.WIDTH{1'b0}};
end
else if (psel & penable & (~pwrite) & pready)
begin
RID <= #FFD cmd_id;
RDATA <= #FFD prdata;
RRESP <= #FFD cmd_err ? RESP_SLVERR : pslverr ? RESP_DECERR : RESP_OK;
RLAST <= #FFD 1'b1;
RVALID <= #FFD 1'b1;
end
endmodule
 
/src/base/axi2apb_wr.v
0,0 → 1,48
INCLUDE def_axi2apb.txt
OUTFILE PREFIX_axi2apb_wr.v
 
module PREFIX_axi2apb_wr (PORTS);
 
input clk;
input reset;
input GROUP_APB3;
input cmd_err;
input [ID_BITS-1:0] cmd_id;
output finish_wr;
port WGROUP_APB_AXI_W;
port BGROUP_APB_AXI_B;
parameter RESP_OK = 2'b00;
parameter RESP_SLVERR = 2'b10;
parameter RESP_DECERR = 2'b11;
reg BGROUP_APB_AXI_B.OUT;
assign finish_wr = BVALID & BREADY;
assign WREADY = psel & penable & pwrite & pready;
always @(posedge clk or posedge reset)
if (reset)
begin
BGROUP_APB_AXI_B.OUT <= #FFD {GROUP_APB_AXI_B.OUT.WIDTH{1'b0}};
end
else if (finish_wr)
begin
BGROUP_APB_AXI_B.OUT <= #FFD {GROUP_APB_AXI_B.OUT.WIDTH{1'b0}};
end
else if (psel & penable & pwrite & pready)
begin
BID <= #FFD cmd_id;
BRESP <= #FFD cmd_err ? RESP_SLVERR : pslverr ? RESP_DECERR : RESP_OK;
BVALID <= #FFD 1'b1;
end
endmodule
 
/src/base/def_axi2apb.txt
0,0 → 1,23
 
INCLUDE def_axi2apb_static.txt
 
SWAP #FFD #1 ## flip-flop delay
 
SWAP PREFIX soc ## prefix for all modules and file names
 
SWAP SLAVE_NUM 8 ## number of APB slaves
 
SWAP CMD_DEPTH 2 ## number of AXI command FIFO
 
SWAP ADDR_BITS 24 ## AXI and APB address bits
SWAP ID_BITS 4 ## AXI ID bits
SWAP DEC_BITS 8 ## Address MSBits for slave decoding
 
SWAP DEC_ADDR0 DEC_BITS'h00 ## Slave 0 address deciding
SWAP DEC_ADDR1 DEC_BITS'h01 ## Slave 1 address deciding
SWAP DEC_ADDR2 DEC_BITS'h02 ## Slave 2 address deciding
SWAP DEC_ADDR3 DEC_BITS'h03 ## Slave 3 address deciding
SWAP DEC_ADDR4 DEC_BITS'h10 ## Slave 4 address deciding
SWAP DEC_ADDR5 DEC_BITS'h11 ## Slave 5 address deciding
SWAP DEC_ADDR6 DEC_BITS'h12 ## Slave 6 address deciding
SWAP DEC_ADDR7 DEC_BITS'h13 ## Slave 7 address deciding
/src/base/axi2apb_mux.v
0,0 → 1,94
INCLUDE def_axi2apb.txt
OUTFILE PREFIX_axi2apb_mux.v
 
ITER SX
module PREFIX_axi2apb_mux (PORTS);
 
 
input clk;
input reset;
input [ADDR_BITS-1:0] cmd_addr;
input psel;
output [31:0] prdata;
output pready;
output pslverr;
output pselSX;
input preadySX;
input pslverrSX;
 
input [31:0] prdataSX;
 
parameter ADDR_MSB = EXPR(ADDR_BITS-1);
parameter ADDR_LSB = EXPR(ADDR_BITS-DEC_BITS);
reg pready;
reg pslverr_pre;
reg pslverr;
reg [31:0] prdata_pre;
reg [31:0] prdata;
reg [SLV_BITS-1:0] slave_num;
always @(*)
begin
casex (cmd_addr[ADDR_MSB:ADDR_LSB])
DEC_ADDRSX : slave_num = SLV_BITS'dSX;
default : slave_num = SLV_BITS'dSLAVE_NUM; //decode error
endcase
end
assign pselSX = psel & (slave_num == SLV_BITS'dSX);
always @(*)
begin
case (slave_num)
SLV_BITS'dSX: pready = preadySX;
default : pready = 1'b1; //decode error
endcase
end
always @(*)
begin
case (slave_num)
SLV_BITS'dSX: pslverr_pre = pslverrSX;
default : pslverr_pre = 1'b1; //decode error
endcase
end
always @(*)
begin
case (slave_num)
SLV_BITS'dSX: prdata_pre = prdataSX;
default : prdata_pre = {32{1'b0}};
endcase
end
always @(posedge clk or posedge reset)
if (reset)
begin
prdata <= #FFD {32{1'b0}};
pslverr <= #FFD 1'b0;
end
else if (psel & pready)
begin
prdata <= #FFD prdata_pre;
pslverr <= #FFD pslverr_pre;
end
else if (~psel)
begin
prdata <= #FFD {32{1'b0}};
pslverr <= #FFD 1'b0;
end
endmodule
 
/src/base/def_axi2apb_static.txt
0,0 → 1,57
 
SWAP SLV_BITS LOG2(EXPR(SLAVE_NUM+1)) ##one more for decerr slave
 
LOOP SX SLAVE_NUM
 
GROUP APB3 is {
psel 1 output
penable 1 output
pwrite 1 output
paddr ADDR_BITS output
pwdata 32 output
prdata 32 input
pslverr 1 input
pready 1 input
}
 
GROUP APB_AXI_A is {
ID ID_BITS input
ADDR ADDR_BITS input
LEN 4 input
SIZE 2 input
VALID 1 input
READY 1 output
}
 
GROUP APB_AXI_W is {
ID ID_BITS input
DATA 32 input
STRB 4 input
LAST 1 input
VALID 1 input
READY 1 output
}
 
GROUP APB_AXI_B is {
ID ID_BITS output
RESP 2 output
VALID 1 output
READY 1 input
}
 
GROUP APB_AXI_R is {
ID ID_BITS output
DATA 32 output
RESP 2 output
LAST 1 output
VALID 1 output
READY 1 input
}
 
GROUP APB_AXI joins {
GROUP APB_AXI_A prefix_AW
GROUP APB_AXI_W prefix_W
GROUP APB_AXI_B prefix_B
GROUP APB_AXI_A prefix_AR
GROUP APB_AXI_R prefix_R
}
/src/base/axi2apb.v
0,0 → 1,122
INCLUDE def_axi2apb.txt
OUTFILE PREFIX_axi2apb.v
 
ITER SX
module PREFIX_axi2apb (PORTS);
 
input clk;
input reset;
 
port GROUP_APB_AXI;
//apb slaves
output penable;
output pwrite;
output [ADDR_BITS-1:0] paddr;
output [31:0] pwdata;
 
output pselSX;
input [31:0] prdataSX;
input preadySX;
input pslverrSX;
 
 
 
wire GROUP_APB3;
//outputs of cmd
wire cmd_empty;
wire cmd_read;
wire [ID_BITS-1:0] cmd_id;
wire [ADDR_BITS-1:0] cmd_addr;
wire cmd_err;
//outputs of rd / wr
wire finish_wr;
wire finish_rd;
assign paddr = cmd_addr;
assign pwdata = WDATA;
 
CREATE axi2apb_cmd.v
PREFIX_axi2apb_cmd PREFIX_axi2apb_cmd(
.clk(clk),
.reset(reset),
.AWGROUP_APB_AXI_A(AWGROUP_APB_AXI_A),
.ARGROUP_APB_AXI_A(ARGROUP_APB_AXI_A),
.finish_wr(finish_wr),
.finish_rd(finish_rd),
.cmd_empty(cmd_empty),
.cmd_read(cmd_read),
.cmd_id(cmd_id),
.cmd_addr(cmd_addr),
.cmd_err(cmd_err)
);
 
CREATE axi2apb_rd.v
PREFIX_axi2apb_rd PREFIX_axi2apb_rd(
.clk(clk),
.reset(reset),
.GROUP_APB3(GROUP_APB3),
.cmd_err(cmd_err),
.cmd_id(cmd_id),
.finish_rd(finish_rd),
.RGROUP_APB_AXI_R(RGROUP_APB_AXI_R),
STOMP ,
);
CREATE axi2apb_wr.v
PREFIX_axi2apb_wr PREFIX_axi2apb_wr(
.clk(clk),
.reset(reset),
.GROUP_APB3(GROUP_APB3),
.cmd_err(cmd_err),
.cmd_id(cmd_id),
.finish_wr(finish_wr),
.WGROUP_APB_AXI_W(WGROUP_APB_AXI_W),
.BGROUP_APB_AXI_B(BGROUP_APB_AXI_B),
STOMP ,
);
CREATE axi2apb_mux.v
PREFIX_axi2apb_mux PREFIX_axi2apb_mux(
.clk(clk),
.reset(reset),
.cmd_addr(cmd_addr),
.psel(psel),
.prdata(prdata),
.pready(pready),
.pslverr(pslverr),
.pselSX(pselSX),
.preadySX(preadySX),
.pslverrSX(pslverrSX),
.prdataSX(prdataSX),
STOMP ,
);
 
CREATE axi2apb_ctrl.v
PREFIX_axi2apb_ctrl PREFIX_axi2apb_ctrl(
.clk(clk),
.reset(reset),
.finish_wr(finish_wr),
.finish_rd(finish_rd),
.cmd_empty(cmd_empty),
.cmd_read(cmd_read),
.WVALID(WVALID),
.psel(psel),
.penable(penable),
.pwrite(pwrite),
.pready(pready)
);
 
endmodule
 
 
/src/base/axi2apb_cmd.v
0,0 → 1,80
INCLUDE def_axi2apb.txt
OUTFILE PREFIX_axi2apb_cmd.v
 
module PREFIX_axi2apb_cmd (PORTS);
 
input clk;
input reset;
 
port AWGROUP_APB_AXI_A;
port ARGROUP_APB_AXI_A;
input finish_wr;
input finish_rd;
output cmd_empty;
output cmd_read;
output [ID_BITS-1:0] cmd_id;
output [ADDR_BITS-1:0] cmd_addr;
output cmd_err;
wire AGROUP_APB_AXI_A;
wire cmd_push;
wire cmd_pop;
reg read;
assign wreq = AWVALID;
assign rreq = ARVALID;
assign wack = AWVALID & AWREADY;
assign rack = ARVALID & ARREADY;
always @(posedge clk or posedge reset)
if (reset)
read <= #FFD 1'b1;
else if (wreq & (rack | (~rreq)))
read <= #FFD 1'b0;
else if (rreq & (wack | (~wreq)))
read <= #FFD 1'b1;
 
//command mux
assign AGROUP_APB_AXI_A = read ? ARGROUP_APB_AXI_A : AWGROUP_APB_AXI_A;
assign AERR = (ASIZE != 'd2) | (ALEN != 'd0); //support only 32 bit single AXI commands
assign ARREADY = (~cmd_full) & read;
assign AWREADY = (~cmd_full) & (~read);
assign cmd_push = AVALID & AREADY;
assign cmd_pop = cmd_read ? finish_rd : finish_wr;
CREATE prgen_fifo.v DEFCMD(SWAP CONST(#FFD) #FFD)
prgen_fifo #(ID_BITS+ADDR_BITS+2, CMD_DEPTH)
cmd_fifo(
.clk(clk),
.reset(reset),
.push(cmd_push),
.pop(cmd_pop),
.din({
AID,
AADDR,
AERR,
read
}
),
.dout({
cmd_id,
cmd_addr,
cmd_err,
cmd_read
}
),
.empty(cmd_empty),
.full(cmd_full)
);
 
endmodule
 
 
/src/base/axi2apb_ctrl.v
0,0 → 1,76
 
INCLUDE def_axi2apb.txt
OUTFILE PREFIX_axi2apb_ctrl.v
 
module PREFIX_axi2apb_ctrl (PORTS);
 
 
input clk;
input reset;
 
input finish_wr;
input finish_rd;
input cmd_empty;
input cmd_read;
input WVALID;
 
output psel;
output penable;
output pwrite;
input pready;
wire wstart;
wire rstart;
reg busy;
reg psel;
reg penable;
reg pwrite;
wire pack;
wire cmd_ready;
 
assign cmd_ready = (~busy) & (~cmd_empty);
assign wstart = cmd_ready & (~cmd_read) & (~psel) & WVALID;
assign rstart = cmd_ready & cmd_read & (~psel);
assign pack = psel & penable & pready;
always @(posedge clk or posedge reset)
if (reset)
busy <= #FFD 1'b0;
else if (psel)
busy <= #FFD 1'b1;
else if (finish_rd | finish_wr)
busy <= #FFD 1'b0;
always @(posedge clk or posedge reset)
if (reset)
psel <= #FFD 1'b0;
else if (pack)
psel <= #FFD 1'b0;
else if (wstart | rstart)
psel <= #FFD 1'b1;
always @(posedge clk or posedge reset)
if (reset)
penable <= #FFD 1'b0;
else if (pack)
penable <= #FFD 1'b0;
else if (psel)
penable <= #FFD 1'b1;
 
always @(posedge clk or posedge reset)
if (reset)
pwrite <= #FFD 1'b0;
else if (pack)
pwrite <= #FFD 1'b0;
else if (wstart)
pwrite <= #FFD 1'b1;
 
endmodule
 
/README.txt
0,0 → 1,20
 
------------------------------ 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.
------------------------------------------------------------------------------
 
RobustVerilog generic AXI to APB bridge
 
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 axi2apb.v, it calls the top definition file named def_axi2apb.txt.
 
The default definition file def_axi2apb.txt generates a bridge with 8 APB slaves.
 
Changing the interconnect parameters should be made only in def_axi2apb.txt in the src/base directory (changing slave num etc.).
 
For any questions / remarks / suggestions / bugs please contact info@provartec.com.
 
 
 

powered by: WebSVN 2.1.0

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