論理回路デザイン
ArchiTek home page
はじめに

サンプルコード

/* **************************** 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 *****************************

        // アドレスマスク、対象に合わせて設定
        parameter               PAM     = 32'hffffffff;

        // バスの語長とバースト長、対象に合わせて設定
        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パス
        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;

        // 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
// Strobe信号が不要なら、$randomの行は使わない
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
// Strobe信号が不要なら、$randomの行は使わない
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

// *****************************************************************************
        

回路デザイン > テスト > バスプロトコルマスター    次のページ(バススレーブ)   このページのTOP ▲