Author: Tran Quang Truong Class: BIC_13052025
Design Decoder Block
Signals descriptions:
PCLK: System clock
PRESETn: Asynchronous reset is low active PSEL: Chip select is high active for the transfer
PWRITE: Write command is High active.
PENABLE: The enable signal is de-asserted at the end of the transfer.
PREADY: The PREADY signal from the slave can extend the transfer.
PSLVERR: Indicate an error condition on an APB transfer.
PADDR[7:0]: Address is used to select the registers A,B,C,D,E,G… PWDATA[7:0]: Data is used to
update selected registers.
PADDR[7:0] Select registers
8’h00 A
8’h01 B
8’h02 C
8’h03 D
8’h04 E
8’h05 F
8’h06 G
8’h07 H
8’h08-8’hff Reserved
Author: Tran Quang Truong Class: BIC_13052025
Figure 4: Block diagram of IP decoder.
Requests:
- Analyzing timing of signals on circuit
- Design digital circuit
- Write verilog for this circuit
- Write testbench to test this block and debug design if there is any error
Timing :
Figure 4-1: Write transfer with no wait states
Figure 4-2: Write transfer with wait states
Author: Tran Quang Truong Class: BIC_13052025
Figure 4-3: Example failing write transfer
RTL design
This is my rtl code about ip decoder
ip_decoder.v
module ip_decoder (
input wire PCLK, // Clock
input wire PRESETn, // Asynchronous Reset (active low)
input wire PSEL, // Peripheral Select
input wire PENABLE, // Enable Phase
input wire PWRITE, // 1 = Write, 0 = Read
input wire [7:0] PADDR, // Address bus
input wire [7:0] PWDATA, // Write data
output reg PREADY, // Ready signal
output reg PSLVERR, // Error signal
output reg [7:0] A, B, C, D, E, F, G, H // 8 output registers
);
// Asynchronous Reset & Write Logic
always @(posedge PCLK or negedge PRESETn) begin
if (!PRESETn) begin
Author: Tran Quang Truong Class: BIC_13052025
// Reset all registers and signals
{A, B, C, D, E, F, G, H} <= 64'd0;
PREADY <= 1'b0;
PSLVERR <= 1'b0;
end else begin
// Default states
PREADY <= 1'b0;
PSLVERR <= 1'b0;
// Only handle in ACCESS phase and write command
if (PSEL && PENABLE && PWRITE) begin
PREADY <= 1'b1; // Always ready (no wait state)
case (PADDR)
8'h00: A <= PWDATA;
8'h01: B <= PWDATA;
8'h02: C <= PWDATA;
8'h03: D <= PWDATA;
8'h04: E <= PWDATA;
8'h05: F <= PWDATA;
8'h06: G <= PWDATA;
8'h07: H <= PWDATA;
default: PSLVERR <= 1'b1; // Invalid address
endcase
end else begin
// Idle or not write access
PREADY <= 1'b0;
PSLVERR <= 1'b0;
end
end
end
endmodule
Author: Tran Quang Truong Class: BIC_13052025
test_bench.v
`timescale 1ns/1ps
module tb_ip_decoder;
// Signal declaration
reg PCLK;
reg PRESETn;
reg PSEL;
reg PENABLE;
reg PWRITE;
reg [7:0] PADDR;
reg [7:0] PWDATA;
wire PREADY;
wire PSLVERR;
wire [7:0] A, B, C, D, E, F, G, H;
// Instantiate the Unit Under Test (UUT)
ip_decoder uut (
.PCLK(PCLK),
.PRESETn(PRESETn),
.PSEL(PSEL),
.PENABLE(PENABLE),
.PWRITE(PWRITE),
.PADDR(PADDR),
.PWDATA(PWDATA),
.PREADY(PREADY),
.PSLVERR(PSLVERR),
.A(A), .B(B), .C(C), .D(D), .E(E), .F(F), .G(G), .H(H)
);
// Clock generation
initial PCLK = 0;
always #5 PCLK = ~PCLK; // 100MHz clock
// Task ghi dữ liệu qua APB
task write_apb(input [7:0] addr, input [7:0] data);
begin
@(posedge PCLK);
Author: Tran Quang Truong Class: BIC_13052025
PSEL = 1;
PENABLE = 0;
PADDR = addr;
PWDATA = data;
PWRITE = 1;
@(posedge PCLK);
PENABLE = 1;
@(posedge PCLK);
PSEL = 0;
PENABLE = 0;
end
endtask
// Test procedure
initial begin
// Initialize
PRESETn = 0;
PSEL = 0;
PENABLE = 0;
PWRITE = 0;
PADDR = 0;
PWDATA = 0;
// Apply reset
repeat (2) @(posedge PCLK);
PRESETn = 1;
write_apb(8'h00, 8'hA0); // A
write_apb(8'h01, 8'hB1); // B
write_apb(8'h02, 8'hC2); // C
write_apb(8'h03, 8'hD3); // D
write_apb(8'h04, 8'hE4); // E
write_apb(8'h05, 8'hF5); // F
write_apb(8'h06, 8'h66); // G
write_apb(8'h07, 8'h77); // H
write_apb(8'hF0, 8'hFF); // PSLVERR expected
Author: Tran Quang Truong Class: BIC_13052025
// Wait a few cycles
repeat (5) @(posedge PCLK);
$display("\n==== Result====");
$display("A = %h", A);
$display("B = %h", B);
$display("C = %h", C);
$display("D = %h", D);
$display("E = %h", E);
$display("F = %h", F);
$display("G = %h", G);
$display("H = %h", H);
$display("PSLVERR = %b", PSLVERR);
$finish;
end
endmodule
Waveform
Comment: The write transaction begins in the Setup Phase when PSEL and PWRITE are asserted high. In
the following clock cycle, the transaction enters the Access Phase as PENABLE is asserted. Because
PREADY is also high, the slave responds immediately, writing the data from PWDATA to the location
specified by PADDR without any wait states.