Hi,
I am trying understand the verification process of AHB lite protocol. I am trying build my resume to add a project to build a Full UVM testbench. I know the concept of AHB lite protocol I have gone through the whole spec twice.
But i want to understand the process of verifying it, so lets say when someone says verification of AHB lite protocol what should it have,
is it just read and write transactions between a single master and one or more slave?
or will there be any inclusions of BFM or should i verify a protocol in such a way that it acts as a bridge between two components and AHB lite protocol will act as a bus for communication between Component A and Component B.
Can someone please guide me bottom line i want to build a Full uvm testbench to verify AHB lite protocol. I want to know what to and how to do , what are all the components should i include in to verify it if necessary.
Thanks,
Teja
AHB - Lite is a single Master and Multi Slave protocol. To verify this protocol, follow below steps.
- Design a simple DUT which does memory read and write using AHB - Lite interface. Which means reads and writes to memory should obey AHB - Lite protocol.
- Write UVM TB which contains all necessary components required like tb_top, test, env,master_agent(drives the data on AHB - Lite interface) ref model, Scoreboard etc.
- Code the master agent which should support all burst features like INCRs, WRAPs.
- Write the assertions to check the timing relationship of the AHB - Lite protocol signals
- Write functional coverage model so as to check you have exercised all possible input combinations or not.
Hope this helps.
1 Like
sir
may you review my code is it in the right direction
// Code your design here
//
// AHB-Lite Memory Controller (DUT)
// Memory Size: 1KB (256 x 32-bit words)
module ahb_lite_memory #(
parameter ADDR_WIDTH = 32,
parameter DATA_WIDTH = 32,
parameter MEM_DEPTH = 256 // 1KB / 4 bytes = 256 words
)(
// Global signals
input logic HCLK,
input logic HRESETn,
// AHB-Lite Master Interface
input logic [ADDR_WIDTH-1:0] HADDR,
input logic [1:0] HTRANS,
input logic HWRITE,
input logic [2:0] HSIZE,
input logic [2:0] HBURST,
input logic [DATA_WIDTH-1:0] HWDATA,
// AHB-Lite Slave Interface
output logic [DATA_WIDTH-1:0] HRDATA,
output logic HREADY,
output logic HRESP
);
// Local Parameters
//
// HTRANS encoding
localparam [1:0] IDLE = 2'b00;
localparam [1:0] BUSY = 2'b01;
localparam [1:0] NONSEQ = 2'b10;
localparam [1:0] SEQ = 2'b11;
// HSIZE encoding
localparam [2:0] SIZE_BYTE = 3'b000; // 8-bit
localparam [2:0] SIZE_HALF = 3'b001; // 16-bit
localparam [2:0] SIZE_WORD = 3'b010; // 32-bit
// HRESP encoding
localparam RESP_OKAY = 1'b0;
localparam RESP_ERROR = 1'b1;
// Memory address range
localparam [ADDR_WIDTH-1:0] MEM_BASE = 32'h0000_0000;
localparam [ADDR_WIDTH-1:0] MEM_TOP = 32'h0000_03FF; // 1KB
// Internal Signals
// Memory array
logic [DATA_WIDTH-1:0] memory [0:MEM_DEPTH-1];
// Pipeline registers for address phase
logic [ADDR_WIDTH-1:0] addr_reg;
logic [1:0] trans_reg;
logic write_reg;
logic [2:0] size_reg;
// Control signals
logic valid_addr;
logic addr_error;
logic [7:0] word_addr;
// Address Phase - Capture control signals
always_ff @(posedge HCLK or negedge HRESETn) begin
if (!HRESETn) begin
addr_reg <= '0;
trans_reg <= IDLE;
write_reg <= 1'b0;
size_reg <= SIZE_WORD;
end else if (HREADY) begin
addr_reg <= HADDR;
trans_reg <= HTRANS;
write_reg <= HWRITE;
size_reg <= HSIZE;
end
end
// Address Validation
assign valid_addr = (trans_reg == NONSEQ || trans_reg == SEQ);
assign addr_error = valid_addr && (addr_reg < MEM_BASE || addr_reg > MEM_TOP);
assign word_addr = addr_reg[9:2]; // Convert byte address to word address
// Data Phase - Memory Read/Write Operations
always_ff @(posedge HCLK or negedge HRESETn) begin
if (!HRESETn) begin
for (int i = 0; i < MEM_DEPTH; i++) begin
memory[i] <= '0;
end
end else if (HREADY && valid_addr && write_reg && !addr_error) begin
// Write operation
case (size_reg)
SIZE_BYTE: begin
// Byte write - use byte offset
case (addr_reg[1:0])
2'b00: memory[word_addr][7:0] <= HWDATA[7:0];
2'b01: memory[word_addr][15:8] <= HWDATA[7:0];
2'b10: memory[word_addr][23:16] <= HWDATA[7:0];
2'b11: memory[word_addr][31:24] <= HWDATA[7:0];
endcase
end
SIZE_HALF: begin
// Halfword write - use halfword offset
case (addr_reg[1])
1'b0: memory[word_addr][15:0] <= HWDATA[15:0];
1'b1: memory[word_addr][31:16] <= HWDATA[15:0];
endcase
end
SIZE_WORD: begin
// Word write
memory[word_addr] <= HWDATA;
end
default: memory[word_addr] <= HWDATA;
endcase
end
end
// Memory Read Operation
always_ff @(posedge HCLK or negedge HRESETn) begin
if (!HRESETn) begin
HRDATA <= '0;
end else if (HREADY && valid_addr && !write_reg && !addr_error) begin
// Read operation
case (size_reg)
SIZE_BYTE: begin
// Byte read - replicate byte to all positions
case (addr_reg[1:0])
2'b00: HRDATA <= {4{memory[word_addr][7:0]}};
2'b01: HRDATA <= {4{memory[word_addr][15:8]}};
2'b10: HRDATA <= {4{memory[word_addr][23:16]}};
2'b11: HRDATA <= {4{memory[word_addr][31:24]}};
endcase
end
SIZE_HALF: begin
// Halfword read - replicate halfword
case (addr_reg[1])
1'b0: HRDATA <= {2{memory[word_addr][15:0]}};
1'b1: HRDATA <= {2{memory[word_addr][31:16]}};
endcase
end
SIZE_WORD: begin
// Word read
HRDATA <= memory[word_addr];
end
default: HRDATA <= memory[word_addr];
endcase
end
end
// Response Generation
always_ff @(posedge HCLK or negedge HRESETn) begin
if (!HRESETn) begin
HRESP <= RESP_OKAY;
end else if (HREADY) begin
HRESP <= addr_error ? RESP_ERROR : RESP_OKAY;
end
end
// Ready Signal - Always ready in this simple implementation
// Can be modified to insert wait states
assign HREADY = 1'b1;
// Assertions for internal checking
//
`ifdef SIMULATION
// Check for X or Z on critical signals
property no_x_on_addr;
@(posedge HCLK) disable iff (!HRESETn)
(HTRANS != IDLE) |-> !$isunknown(HADDR);
endproperty
property no_x_on_wdata;
@(posedge HCLK) disable iff (!HRESETn)
(write_reg && valid_addr) |-> !$isunknown(HWDATA);
endproperty
assert property (no_x_on_addr) else
$error("X or Z detected on HADDR during valid transfer");
assert property (no_x_on_wdata) else
$error("X or Z detected on HWDATA during write");
`endif
endmodule