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. |
|
|
|