Logical circuit design |
|
/* **************************** 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 ▲