URL
https://opencores.org/ocsvn/ahb_slave/ahb_slave/trunk
Subversion Repositories ahb_slave
Compare Revisions
- This comparison shows the changes necessary to convert path
/ahb_slave
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/trunk/src/gen/prgen_rand.v
0,0 → 1,59
|
function integer rand_chance; |
input [31:0] chance_true; |
|
begin |
if (chance_true > 100) |
begin |
$display("RAND_CHANCE-E-: fatal error, rand_chance called with percent chance larger than 100.\tTime: %0d ns", $time); |
$finish; |
end |
rand_chance = (rand(1,100) <= chance_true); |
end |
endfunction // rand_chance |
|
|
function integer rand; |
input [31:0] min; |
input [31:0] max; |
|
integer range; |
begin |
if (min > max) |
begin |
$display("RAND-E-: fatal error, rand was called with min larger than max.\tTime: %0d ns", $time); |
$finish; |
end |
|
range = (max - min) + 1; |
if (range == 0) range = -1; |
rand = min + ($random % range); |
end |
endfunction // rand |
|
|
function integer align; |
input [31:0] num; |
input [31:0] align_size; |
|
integer align; |
begin |
align = num - (num % align_size); |
end |
endfunction |
|
|
function integer rand_align; |
input [31:0] min; |
input [31:0] max; |
input [31:0] align; |
|
integer rand_align; |
begin |
rand_align = rand(min, max); |
|
if (rand_align > align) |
rand_align = align(rand_align, align); |
end |
endfunction |
|
/trunk/src/base/def_ahb_slave.txt
0,0 → 1,12
|
INCLUDE def_ahb_slave_static.txt |
|
SWAP.GLOBAL #FFD #1 ##Flip-Flop simulation delay |
|
SWAP PREFIX ahb_slave ##prefix for all module and file names |
|
SWAP ADDR_BITS 24 ##AHB address bits |
SWAP DATA_BITS 32 ##AHB data bits |
|
##DEFINE TRACE ##print memory trace to file |
|
/trunk/src/base/ahb_slave_mem.v
0,0 → 1,36
|
OUTFILE PREFIX_mem.v |
|
INCLUDE def_ahb_slave.txt |
|
ITER BX EXPR(DATA_BITS/8) |
module PREFIX_mem (PORTS); |
|
parameter MEM_WORDS = EXPR((2^ADDR_BITS)/(DATA_BITS/8)); |
parameter ADDR_LSB = LOG2(EXPR(DATA_BITS/8)); |
|
input clk; |
input reset; |
revport GROUP_STUB_MEM; |
|
reg [DATA_BITS-1:0] Mem [MEM_WORDS-1:0]; |
reg [DATA_BITS-1:0] DOUT; |
wire [DATA_BITS-1:0] BitSEL; |
wire [ADDR_BITS-1:ADDR_LSB] ADDR_WR_word = ADDR_WR[ADDR_BITS-1:ADDR_LSB]; |
wire [ADDR_BITS-1:ADDR_LSB] ADDR_RD_word = ADDR_RD[ADDR_BITS-1:ADDR_LSB]; |
|
|
assign BitSEL = {CONCAT({8{BSEL[BX]}} ,)}; |
|
always @(posedge clk) |
if (WR) |
Mem[ADDR_WR_word] <= #FFD (Mem[ADDR_WR_word] & ~BitSEL) | (DIN & BitSEL); |
|
always @(posedge clk or posedge reset) |
if (reset) |
DOUT <= #FFD {DATA_BITS{1'b0}}; |
else if (RD) |
DOUT <= #FFD Mem[ADDR_RD_word]; |
|
|
endmodule |
/trunk/src/base/ahb_slave_trace.v
0,0 → 1,53
|
OUTFILE PREFIX_trace.v |
|
INCLUDE def_ahb_slave.txt |
|
module PREFIX_trace(PORTS); |
|
parameter SLAVE_NUM = 0; |
|
parameter FILE_NAME = "PREFIX.trc"; |
|
input clk; |
input reset; |
|
input GROUP_STUB_MEM; |
|
|
reg RD_d; |
reg [ADDR_BITS-1:0] ADDR_RD_d; |
|
wire [31:0] ADDR_WR_disp = ADDR_WR; |
wire [31:0] ADDR_RD_disp = ADDR_RD_d; |
|
integer file_ptr; |
|
initial |
file_ptr = $fopen(FILE_NAME, "w"); |
|
|
always @(posedge clk or posedge reset) |
if (reset) |
begin |
ADDR_RD_d <= #FFD 'd0; |
RD_d <= #FFD 'd0; |
end |
else |
begin |
ADDR_RD_d <= #FFD ADDR_RD; |
RD_d <= #FFD RD; |
end |
|
always @(posedge clk) |
if (WR) |
$fwrite(file_ptr, "%16d: %0s WR: Addr: 0x%8h, Data: 0x%8h, Bsel: 0x%2h\n", $time, FILE_NAME, ADDR_WR_disp, DIN, BSEL); |
|
always @(posedge clk) |
if (RD_d) |
$fwrite(file_ptr, "%16d: %0s RD: Addr: 0x%8h, Data: 0x%8h\n", $time, FILE_NAME, ADDR_RD_disp, DOUT); |
|
|
endmodule |
|
|
/trunk/src/base/ahb_slave_ram.v
0,0 → 1,187
|
OUTFILE PREFIX_ram.v |
|
INCLUDE def_ahb_slave.txt |
|
CHECK CONST(#FFD) |
CHECK CONST(PREFIX) |
CHECK CONST(ADDR_BITS) |
CHECK CONST(DATA_BITS) |
|
module PREFIX_ram(PORTS); |
|
input clk; |
input reset; |
|
revport GROUP_STUB_AHB; |
|
port GROUP_STUB_MEM; |
|
|
`include "prgen_rand.v" |
|
|
//---------------- config parameters ------------------------ |
reg stall_enable = 1; //enable stall on HREADY |
integer burst_chance = 1; //chance for burst on HREADY stall |
integer burst_len = 10; //length of stall burst in cycles |
integer burst_val = 90; //chance for stall during burst |
integer stall_chance = 10; //chance for stall |
|
reg [ADDR_BITS-1:0] HRESP_addr = {ADDR_BITS{1'b1}}; //address for response error |
reg [ADDR_BITS-1:0] TIMEOUT_addr = {ADDR_BITS{1'b1}}; //address for timeout response (no HREADY) |
//----------------------------------------------------------- |
|
|
integer burst_stall; |
integer stall_chance_valid; |
|
reg HRESP; |
reg timeout_stall; |
|
reg [1:0] HSIZE_d; |
wire WR_pre; |
wire [ADDR_BITS-1:0] ADDR_WR_pre; |
reg WR; |
reg [ADDR_BITS-1:0] ADDR_WR; |
reg data_phase; |
|
wire [7:0] BSEL_wide; |
|
reg STALL_pre; |
reg STALL; |
|
|
parameter TRANS_IDLE = 2'b00; |
parameter TRANS_STALL = 2'b01; |
parameter TRANS_NONSEQ = 2'b10; |
parameter TRANS_SEQ = 2'b11; |
|
|
task set_stall; |
begin |
stall_chance_valid = 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; |
stall_chance_valid = burst_val; |
repeat (burst_len) @(posedge clk); |
set_stall; |
end |
else |
begin |
@(posedge clk); |
end |
end |
end |
|
|
always @(posedge clk) |
begin |
#FFD; |
STALL_pre = rand_chance(stall_chance_valid); |
end |
|
|
always @(posedge clk or posedge reset) |
if (reset) |
STALL <= #FFD 1'b0; |
else if (stall_enable) |
STALL <= #FFD STALL_pre; |
else |
STALL <= #FFD 1'b0; |
|
always @(posedge clk or posedge reset) |
if (reset) |
timeout_stall <= #FFD 1'b0; |
else if ((|HTRANS) & (TIMEOUT_addr == HADDR)) |
timeout_stall <= #FFD 1'b1; |
else if (TIMEOUT_addr == 0) |
timeout_stall <= #FFD 1'b0; |
|
always @(posedge clk or posedge reset) |
if (reset) |
HRESP <= #FFD 1'b0; |
else if ((|HTRANS) & (HRESP_addr == HADDR)) |
HRESP <= #FFD 1'b1; |
else if (HREADY) |
HRESP <= #FFD 1'b0; |
|
always @(posedge clk or posedge reset) |
if (reset) |
data_phase <= #FFD 1'b0; |
else if (RD) |
data_phase <= #FFD 1'b1; |
else if (HREADY) |
data_phase <= #FFD 1'b0; |
|
assign HRDATA = HREADY & data_phase ? DOUT : 'd0; |
assign HREADY = HTRANS == TRANS_STALL ? 1'b0 : (~timeout_stall) & (~STALL); |
|
|
assign WR_pre = HWRITE & ((HTRANS == TRANS_NONSEQ) | (HTRANS == TRANS_SEQ)); |
assign RD = (~HWRITE) & ((HTRANS == TRANS_NONSEQ) | (HTRANS == TRANS_SEQ)) & HREADY; |
assign ADDR_WR_pre = {ADDR_BITS{WR_pre}} & HADDR; |
assign ADDR_RD = {ADDR_BITS{RD}} & HADDR; |
assign DIN = HWDATA; |
|
IFDEF TRUE(DATA_BITS==32) |
assign BSEL = ADDR_WR[2] ? BSEL_wide[7:4] : BSEL_wide[3:0]; |
ELSE TRUE(DATA_BITS==32) |
assign BSEL = BSEL_wide; |
ENDIF TRUE(DATA_BITS==32) |
|
assign BSEL_wide = |
(HSIZE_d == 2'b00) & (ADDR_WR[2:0] == 3'd0) ? 8'b0000_0001 : |
(HSIZE_d == 2'b00) & (ADDR_WR[2:0] == 3'd1) ? 8'b0000_0010 : |
(HSIZE_d == 2'b00) & (ADDR_WR[2:0] == 3'd2) ? 8'b0000_0100 : |
(HSIZE_d == 2'b00) & (ADDR_WR[2:0] == 3'd3) ? 8'b0000_1000 : |
(HSIZE_d == 2'b00) & (ADDR_WR[2:0] == 3'd4) ? 8'b0001_0000 : |
(HSIZE_d == 2'b00) & (ADDR_WR[2:0] == 3'd5) ? 8'b0010_0000 : |
(HSIZE_d == 2'b00) & (ADDR_WR[2:0] == 3'd6) ? 8'b0100_0000 : |
(HSIZE_d == 2'b00) & (ADDR_WR[2:0] == 3'd7) ? 8'b1000_0000 : |
|
(HSIZE_d == 2'b01) & (ADDR_WR[2:1] == 2'd0) ? 8'b0000_0011 : |
(HSIZE_d == 2'b01) & (ADDR_WR[2:1] == 2'd1) ? 8'b0000_1100 : |
(HSIZE_d == 2'b01) & (ADDR_WR[2:1] == 2'd2) ? 8'b0011_0000 : |
(HSIZE_d == 2'b01) & (ADDR_WR[2:1] == 2'd3) ? 8'b1100_0000 : |
|
(HSIZE_d == 2'b10) & (ADDR_WR[2] == 1'd0) ? 8'b0000_1111 : |
(HSIZE_d == 2'b10) & (ADDR_WR[2] == 1'd1) ? 8'b1111_0000 : |
|
8'b1111_1111; |
|
|
always @(posedge clk or posedge reset) |
if (reset) |
begin |
WR <= #FFD 1'b0; |
ADDR_WR <= #FFD {ADDR_BITS{1'b0}}; |
HSIZE_d <= #FFD 2'b0; |
end |
else if (HREADY) |
begin |
WR <= #FFD WR_pre; |
ADDR_WR <= #FFD ADDR_WR_pre; |
HSIZE_d <= #FFD HSIZE; |
end |
|
|
endmodule |
|
|
|
|
/trunk/src/base/def_ahb_slave_static.txt
0,0 → 1,27
|
VERIFY ((DATA_BITS == 64) || (DATA_BITS == 32)) else stub supports 32 or 64 bits data bus |
VERIFY (ADDR_BITS<=24) else Memory size should not be too big to prevent maloc fail |
|
GROUP STUB_AHB is { |
HADDR ADDR_BITS output |
HBURST 3 output |
HSIZE 2 output |
HTRANS 2 output |
HWRITE 1 output |
HWDATA DATA_BITS output |
HRDATA DATA_BITS input |
HREADY 1 input |
HRESP 1 input |
} |
|
|
GROUP STUB_MEM is { |
WR 1 output |
RD 1 output |
ADDR_WR ADDR_BITS output |
ADDR_RD ADDR_BITS output |
DIN DATA_BITS output |
BSEL DATA_BITS/8 output |
DOUT DATA_BITS input |
} |
|
/trunk/src/base/ahb_slave.v
0,0 → 1,55
|
OUTFILE PREFIX.v |
|
INCLUDE def_ahb_slave.txt |
|
module PREFIX(PORTS); |
|
parameter SLAVE_NUM = 0; |
|
input clk; |
input reset; |
|
revport GROUP_STUB_AHB; |
|
|
|
wire GROUP_STUB_MEM; |
|
|
|
CREATE ahb_slave_ram.v |
PREFIX_ram PREFIX_ram( |
.clk(clk), |
.reset(reset), |
.GROUP_STUB_AHB(GROUP_STUB_AHB), |
.GROUP_STUB_MEM(GROUP_STUB_MEM), |
STOMP , |
); |
|
|
CREATE ahb_slave_mem.v |
PREFIX_mem PREFIX_mem( |
.clk(clk), |
.reset(reset), |
.GROUP_STUB_MEM(GROUP_STUB_MEM), |
STOMP , |
); |
|
|
|
IFDEF TRACE |
CREATE ahb_slave_trace.v |
PREFIX_trace #(SLAVE_NUM) |
PREFIX_trace( |
.clk(clk), |
.reset(reset), |
.GROUP_STUB_MEM(GROUP_STUB_MEM), |
STOMP , |
); |
|
ENDIF TRACE |
|
endmodule |
|
|
/trunk/README.txt
0,0 → 1,22
|
------------------------------ Remark ---------------------------------------- |
This code is a generic code written in RobustVerilog. In order to convert it to Verilog a RobustVerilog parser is required. |
It is possible to download a free RobustVerilog parser from www.provartec.com/edatools. |
|
We will be very happy to receive any kind of feedback regarding our tools and cores. |
We will also be willing to support any company intending to integrate our cores into their project. |
For any questions / remarks / suggestions / bugs please contact info@provartec.com. |
------------------------------------------------------------------------------ |
|
RobustVerilog generic AHB slave stub |
|
Supports 32 and 64 data bits. |
|
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_slave.v, it calls the top definition file named def_ahb_slave.txt. |
|
The default definition file def_ahb_slave.txt generates an AHB slave with a 32 bit data bus. |
|
Changing the stub parameters should be made only in def_ahb_slave.txt in the src/base directory (adding trace, address bits, data width etc.). |
|