0% found this document useful (0 votes)
18 views9 pages

AHB to APB Bridge RTL Module

The document describes a Verilog module named 'bridge_rtl' that implements an AHB to APB bridge with a finite state machine (FSM) for handling read and write transactions. It includes state definitions, input/output declarations, and the logic for managing the state transitions based on the AHB signals. Additionally, a testbench module 'tb_bridge_rtl' is provided to simulate the bridge's functionality, including clock generation and stimulus for AHB read and write operations.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views9 pages

AHB to APB Bridge RTL Module

The document describes a Verilog module named 'bridge_rtl' that implements an AHB to APB bridge with a finite state machine (FSM) for handling read and write transactions. It includes state definitions, input/output declarations, and the logic for managing the state transitions based on the AHB signals. Additionally, a testbench module 'tb_bridge_rtl' is provided to simulate the bridge's functionality, including clock generation and stimulus for AHB read and write operations.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

module bridge_rtl (

input wire hclk,

input wire hresetn,

input wire hselapb,

input wire hwrite,

input wire [1:0] htrans,

input wire [31:0] haddr,

input wire [31:0] hwdata,

input wire [31:0] prdata,

input wire pready, // APB ready

input wire pslverr, // APB error

output reg [31:0] paddr,

output reg [31:0] pwdata,

output reg psel,

output reg penable,

output reg pwrite,

output reg hresp,

output reg hready,

output reg [31:0] hrdata

);

// State encoding

parameter IDLE = 3'b000;

parameter READ = 3'b001;

parameter RENABLE = 3'b010;

parameter WWAIT = 3'b011;

parameter WRITE = 3'b100;

parameter WENABLE = 3'b101;

reg [2:0] present_state, next_state;


reg [31:0] haddr_temp, hwdata_temp;

reg hwrite_temp;

reg valid;

// Valid AHB transfer detect

always @(*) begin

if (hselapb && (htrans == 2'b10 || htrans == 2'b11)) // NONSEQ or SEQ

valid = 1'b1;

else

valid = 1'b0;

end

// Sequential state update

always @(posedge hclk or negedge hresetn) begin

if (!hresetn)

present_state <= IDLE;

else

present_state <= next_state;

end

// FSM outputs and next state logic

always @(*) begin

// defaults

psel = 1'b0;

penable = 1'b0;

pwrite = 1'b0;

paddr = 32'b0;

pwdata = 32'b0;

hready = 1'b1;

hresp = 1'b0;

hrdata = 32'b0;
next_state = present_state;

case (present_state)

// -----------------------------------

IDLE: begin

if (valid && !hwrite) next_state = READ;

else if (valid && hwrite) next_state = WWAIT;

else next_state = IDLE;

end

// -----------------------------------

READ: begin

psel = 1'b1;

paddr = haddr;

pwrite = 1'b0;

penable = 1'b0;

hready = 1'b0;

next_state = RENABLE;

end

RENABLE: begin

psel = 1'b1;

penable = 1'b1;

pwrite = 1'b0;

paddr = haddr;

hrdata = prdata;

if (pready) begin

hready = 1'b1;

hresp = pslverr;

if (valid && !hwrite) next_state = READ;

else if (valid && hwrite) next_state = WWAIT;


else next_state = IDLE;

end else begin

hready = 1'b0;

next_state = RENABLE;

end

end

// -----------------------------------

WWAIT: begin

haddr_temp = haddr;

hwdata_temp = hwdata;

hwrite_temp = hwrite;

hready = 1'b0;

next_state = WRITE;

end

WRITE: begin

psel = 1'b1;

paddr = haddr_temp;

pwdata = hwdata_temp;

pwrite = 1'b1;

penable = 1'b0;

hready = 1'b0;

next_state = WENABLE;

end

WENABLE: begin

psel = 1'b1;

penable = 1'b1;

pwrite = 1'b1;

paddr = haddr_temp;
pwdata = hwdata_temp;

if (pready) begin

hready = 1'b1;

hresp = pslverr;

if (valid && !hwrite) next_state = READ;

else if (valid && hwrite) next_state = WWAIT;

else next_state = IDLE;

end else begin

hready = 1'b0;

next_state = WENABLE;

end

end

endcase

end

endmodule
module tb_bridge_rtl;

reg hclk;

reg hresetn;

reg hselapb;

reg hwrite;

reg [1:0] htrans;

reg [31:0] haddr;

reg [31:0] hwdata;

wire [31:0] hrdata;

wire hready;

wire hresp;

// APB side signals

wire [31:0] paddr, pwdata;

wire psel, penable, pwrite;

reg [31:0] prdata;

reg pready;

reg pslverr;

// DUT instantiation

bridge_rtl dut (

.hclk(hclk),

.hresetn(hresetn),

.hselapb(hselapb),

.hwrite(hwrite),

.htrans(htrans),

.haddr(haddr),

.hwdata(hwdata),

.prdata(prdata),

.pready(pready),
.pslverr(pslverr),

.paddr(paddr),

.pwdata(pwdata),

.psel(psel),

.penable(penable),

.pwrite(pwrite),

.hresp(hresp),

.hready(hready),

.hrdata(hrdata)

);

// Clock gen

initial begin

hclk = 0;

forever #5 hclk = ~hclk; // 100 MHz clock

end

// Simple APB slave: just one register

reg [31:0] apb_reg;

always @(posedge hclk) begin

if (psel && penable && pwrite && pready) begin

apb_reg <= pwdata; // Write to register

end

end

always @(*) begin

if (psel && !pwrite) begin

prdata = apb_reg; // Read back register

end else begin

prdata = 32'hDEAD_BEEF; // Default

end
end

// Stimulus

initial begin

// Init

hresetn = 0;

hselapb =0;

hwrite = 0;

htrans = 2'b00;

haddr = 32'b0;

hwdata = 32'b0;

pready = 1;

pslverr = 0;

apb_reg = 32'h12345678;

// Apply reset

#20 hresetn = 1;

// -------------------------------

// AHB WRITE transaction

// -------------------------------

@(posedge hclk);

hselapb = 1;

htrans = 2'b10; // NONSEQ

hwrite = 1;

haddr = 32'h0000_0004;

hwdata = 32'hA5A5_F00D;

@(posedge hclk);

hselapb = 0; // deassert after single beat

htrans = 2'b00;

// Wait for APB completion


repeat(4) @(posedge hclk);

// -------------------------------

// AHB READ transaction

// -------------------------------

@(posedge hclk);

hselapb = 1;

htrans = 2'b10; // NONSEQ

hwrite = 0;

haddr = 32'h0000_0004;

@(posedge hclk);

hselapb = 0;

htrans = 2'b00;

// Wait for read data

repeat(4) @(posedge hclk);

// -------------------------------

// End sim

// -------------------------------

$display("APB register value = %h", apb_reg);

$display("Read data from HRDATA = %h", hrdata);

$finish;

end

endmodule

You might also like