Preface
- For bus protocolchecker, master module is prepared.
- Alongwith generating Request and Data, memory prepared internally is updated by Write. Read Data and internal memory contents are compared as expected values. If there is a difference then will output a message.
- Internal memory is not initialized hence, Read from parts where there is no Write will be unknown. Matching the convenience of this test module, will initialize for higher modules.
Sample Code
/* **************************** MODULE PREAMBLE ********************************
Copyright (c) 2012, ArchiTek
This document constitutes confidential and proprietary information
of ArchiTek. All rights reserved.
*/
// ***************************** MODULE HEADER *********************************
module master (
req, gnt, rxw, addr,
wrStrb, wrAck, wrFlush, wrData, wrMask,
rdStrb, rdAck, rdFlush, rdData,
omit,
reset, clk
);
// ************************ PARAMETER DECLARATIONS *****************************
// Address mask, set according to target
parameter PAM = 32'hffffffff;
// Bus word length and burst length, set according to target
parameter NLR = 2; // Word Length Radix
parameter BLR = 2; // Burst Length Radix
parameter NL = 1<<NLR;
parameter NBL = 8<<NLR;
parameter BL = 1<<BLR;
// ***************************** I/O DECLARATIONS ******************************
// Request Bus
output req;
input gnt;
output rxw;
output [31:0] addr;
// Write Dataパス
output wrStrb;
input wrAck;
input wrFlush;
output [NBL-1:0] wrData;
output [NL-1:0] wrMask;
// Read Dataパス
output rdStrb;
input rdAck;
input rdFlush;
input [NBL-1:0] rdData;
// Access prohibit with 1
input omit;
input reset;
input clk;
// ************************** LOCAL DECLARATIONS *******************************
reg req;
reg rxw;
reg [31:0] addr;
reg [BL*NBL-1:0] wd;
reg [BL*NL-1:0] wm;
reg wrStrb;
reg [BLR-1:0] wrCnt;
wire wrDone;
wire wrAlloc = wrStrb & wrAck;
reg rdStrb;
reg [BLR-1:0] rdCnt;
wire rdDone;
wire rdAlloc = rdStrb & rdAck;
reg [10:0] iwPtr, owPtr;
wire [10:0] iwPtrD, owPtrD;
reg [31:0] waFIFO[0:1023];
reg [BL*NBL-1:0] wdFIFO[0:1023];
reg [BL*NL-1:0] wmFIFO[0:1023];
reg [10:0] irPtr, orPtr;
wire [10:0] irPtrD, orPtrD;
reg [31:0] raFIFO[0:1023];
reg [BL*NBL-1:0] rdFIFO[0:1023];
wire owAlloc = wrAlloc & wrDone;
wire [31:0] owAddr = waFIFO[owPtr[9:0]];
wire [BL*NBL-1:0] owData = wdFIFO[owPtr[9:0]];
wire [BL*NL-1:0] owMask = wmFIFO[owPtr[9:0]];
wire orAlloc = rdAlloc & rdDone;
wire [31:0] orAddr = raFIFO[orPtr[9:0]];
wire [BL*NBL-1:0] orData = rdFIFO[orPtr[9:0]];
wire [NBL-1:0] orExp;
wire alloc = req & gnt;
wire iwAlloc = alloc & !rxw;
wire irAlloc = alloc & rxw;
wire diff;
reg [BL*NBL-1:0] mem[0:'h10_0000-1];
wire [BL*NBL-1:0] mask = maskFunc(wm);
wire [BL*NBL-1:0] rdata = mem[addr[31:BLR+NLR]];
wire [BL*NBL-1:0] wdata = wd & ~mask | rdata & mask;
integer i;
// ******************************** MODULE BODY ********************************
// -----------------------------------------------------------------------------
// Req
always @(posedge clk)
if (reset)
req <= #1 1'b0;
else if (!req | gnt)
req <= #1 !omit &
$random &
notFullFunc(irPtrD, orPtrD) &
notFullFunc(iwPtrD, owPtrD);
always @(posedge clk)
if (reset) begin
rxw <= #1 1'b0;
addr <= #1 32'd0;
end
else if (!req | gnt) begin
rxw <= #1 $random;
// addr <= #1 (addr + (1<<BLR+NLR)) & PAM; // Marching
addr <= #1 $random & PAM;
end
always @(posedge clk)
if (reset) begin
iwPtr <= #1 11'd0;
owPtr <= #1 11'd0;
irPtr <= #1 11'd0;
orPtr <= #1 11'd0;
end
else begin
iwPtr <= #1 iwPtrD;
owPtr <= #1 owPtrD;
irPtr <= #1 irPtrD;
orPtr <= #1 orPtrD;
end
assign iwPtrD = iwPtr + iwAlloc;
assign owPtrD = owPtr + owAlloc;
assign irPtrD = irPtr + irAlloc;
assign orPtrD = orPtr + orAlloc;
// -----------------------------------------------------------------------------
// Write Signal Assert
// If Strobe signal is not required, $random row is not used.
always @(posedge clk)
if (reset)
wrStrb <= #1 1'b0;
else
wrStrb <= #1 notEmptyFunc(iwPtrD, owPtrD);
// wrStrb <= #1 notEmptyFunc(iwPtrD, owPtrD) & $random;
always @(posedge clk)
for (i=0; i<BL*NBL; i=i+1)
wd[i] <= #1 $random;
always @(posedge clk)
wm <= #1 $random;
always @(posedge clk)
if (iwAlloc) begin
waFIFO[iwPtr[9:0]] <= #1 addr;
wdFIFO[iwPtr[9:0]] <= #1 wd;
wmFIFO[iwPtr[9:0]] <= #1 wm;
end
always @(posedge clk)
if (iwAlloc)
mem[addr[31:BLR+NLR]] <= #1 wdata;
always @(posedge clk)
if (reset)
wrCnt <= #1 {BLR{1'b0}};
else if (wrAlloc)
wrCnt <= #1 wrDone ? {BLR{1'b0}} : wrCnt + 'h1;
assign wrDone = &wrCnt | wrFlush;
assign wrData = selDataFunc(owData, wrCnt + owAddr[BLR+NLR-1:NLR]);
assign wrMask = selMaskFunc(owMask, wrCnt + owAddr[BLR+NLR-1:NLR]);
// -----------------------------------------------------------------------------
// Read Signal Assert
// If Strobe signal is not required, $random row is not used.
always @(posedge clk)
if (reset)
rdStrb <= #1 1'b0;
else
rdStrb <= #1 notEmptyFunc(irPtrD, orPtrD);
// rdStrb <= #1 notEmptyFunc(irPtrD, orPtrD) & $random;
always @(posedge clk)
if (irAlloc) begin
raFIFO[irPtr[9:0]] <= #1 addr;
rdFIFO[irPtr[9:0]] <= #1 rdata;
end
always @(posedge clk)
if (reset)
rdCnt <= #1 {BLR{1'b0}};
else if (rdAlloc)
rdCnt <= #1 rdDone ? {BLR{1'b0}} : rdCnt + 'h1;
assign rdDone = &rdCnt | rdFlush;
assign orExp = selDataFunc(orData, rdCnt + orAddr[BLR+NLR-1:NLR]);
// -----------------------------------------------------------------------------
// Read Check
always @(posedge clk)
if (!reset)
if (diff | (diff === 1'bx))
$display("Read Error\t(%d): [%32x]\t%x\t(%x?)",
$stime, orAddr, rdData, orExp);
assign diff = rdAlloc & (rdData != orExp);
// **************************** FUNCTIONS and TASKS ****************************
function [BL*NBL-1:0] maskFunc;
input [BL*NL-1:0] mask;
integer i, j;
for (i=0; i<BL*NL; i=i+1)
for (j=0; j<8; j=j+1)
maskFunc[8*i+j] = mask[i];
endfunction
function [NBL-1:0] selDataFunc;
input [BL*NBL-1:0] data;
input [BLR-1:0] sel;
integer i;
for (i=0; i<NBL; i=i+1)
selDataFunc[i] = data[(sel<<NLR+3)+i];
endfunction
function [NL-1:0] selMaskFunc;
input [BL*BL-1:0] mask;
input [BLR-1:0] sel;
integer i;
for (i=0; i<NL; i=i+1)
selMaskFunc[i] = mask[(sel<<NLR)+i];
endfunction
function notEmptyFunc;
input [10:0] ip;
input [10:0] op;
notEmptyFunc = (ip != op);
endfunction
function notFullFunc;
input [10:0] ip;
input [10:0] op;
notFullFunc = (ip[10] == op[10])
| (ip[9:0] != op[9:0]);
endfunction
endmodule
// *****************************************************************************
Logical Circuit Design > Test > Bus protocol master Next page(Bus slave) TOP of this page ▲