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

powered by: WebSVN 2.1.0

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