Logical circuit design
Inquiry Sitemap Link Tips
Preface

Sample code

/* **************************** MODULE PREAMBLE ********************************

        Copyright (c) 2012, ArchiTek
        This document constitutes confidential and proprietary information
        of ArchiTek. All rights reserved.
*/

// ***************************** MODULE HEADER *********************************

module slave (
        req, gnt, rxw, burst, addr,
        wrStrb, wrAck, wrData, wrMask,
        rdStrb, rdAck, rdData,
        reset, clk
        );

// ************************ PARAMETER DECLARATIONS *****************************

        // 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, burst length(burst) specify within BLR range
        output                  req;
        input                   gnt;
        output                  rxw;
        input   [BLR-1:0]       burst;
        output  [31:0]          addr;

        // Write Data Bus
        output                  wrStrb;
        input                   wrAck;
        output  [NBL-1:0]       wrData;
        output  [NL-1:0]        wrMask;

        // Read Data Bus
        output                  rdStrb;
        input                   rdAck;
        input   [NBL-1:0]       rdData;

        input                   reset;
        input                   clk;

// ************************** LOCAL DECLARATIONS *******************************

        reg     [32+BLR:0]      aFIFO[0:31];
        reg                     aBusy, aFull;
        wire                    aBusyD, aFullD;
        wire                    iAlloc;
        reg     [5:0]           iaPtr, oaPtr;
        wire    [5:0]           iaPtrD, oaPtrD;
        wire                    oRxw;
        wire    [BLR-1:0]       oBurst;
        wire    [31:0]          oAddr;
        wire                    oAlloc;

        reg     [BLR-1:0]       oCnt;
        wire                    oDone;
        wire    [BLR-1:0]       oMod;

        reg     [NBL-1:0]       wdFIFO[0:127];
        reg     [NL-1:0]        wmFIFO[0:127];
        reg                     wBusy, wFull;
        wire                    wBusyD, wFullD;
        reg     [7:0]           iwPtr, owPtr;
        wire    [7:0]           iwPtrD, owPtrD;
        wire                    iwAlloc;

        wire                    irAlloc;

        wire    [NBL-1:0]       owData;
        wire    [NL-1:0]        owMask;
        reg     [BL*NBL-1:0]    mask;
        wire                    owAlloc;

        reg     [NBL-11:0]      rdFIFO[0:127];
        reg                     rBusy, rFull;
        wire                    rBusyD, rFullD;
        reg     [7:0]           irPtr, orPtr;
        wire    [7:0]           irPtrD, orPtrD;
        wire                    orAlloc;

        reg     [BL*NBL-1:0]    mem[0:'h10_0000-1];

        integer                 i, j;

// ******************************** MODULE BODY ********************************

// -----------------------------------------------------------------------------
// Req
always @(posedge clk)
        if (iAlloc)
                aFIFO[iaPtr[4:0]]       <= #1 {rxw, burst, addr};

always @(posedge clk)
        if (reset) begin
                aBusy           <= #1 1'b0;
                aFull           <= #1 1'b0;
                iaPtr           <= #1 6'h00;
                oaPtr           <= #1 6'h00;
        end
        else begin
                aBusy           <= #1 aBusyD;
                aFull           <= #1 aFullD;
                iaPtr           <= #1 iaPtrD;
                oaPtr           <= #1 oaPtrD;
        end

assign aFullD           = (iaPtrD[5] != oaPtrD[5]) & (iaPtrD[4:0] == oaPtrD[4:0]);
assign aBusyD           = (iaPtrD != oaPtrD);
assign iaPtrD           = iaPtr + iAlloc;
assign oaPtrD           = oaPtr + (oAlloc & oDone);

assign iAlloc           = req & gnt;

assign {oRxw, oBurst, oAddr}
                        = aFIFO[oaPtr[4:0]];

assign oAlloc           = aBusy & (oRxw ? !rFull : wBusy);

assign gnt              = !aFull;

// -----------------------------------------------------------------------------
// Req Information
always @(posedge clk)
        if (reset)
                oCnt            <= #1 'h0;
        else if (oAlloc)
                oCnt            <= #1 oDone ? 'h0 : oCnt + 'h1;

assign oDone            = (oCnt == oBurst);
assign oMod             = oCnt + oAddr[BLR+1:2];

// -----------------------------------------------------------------------------
// Write Data
always @(posedge clk)
        if (iwAlloc) begin
                wdFIFO[iwPtr[6:0]]      <= #1 wrData;
                wmFIFO[iwPtr[6:0]]      <= #1 wrMask;
        end

always @(posedge clk)
        if (reset) begin
                wFull           <= #1 1'b0;
                wBusy           <= #1 1'b0;
                iwPtr           <= #1 8'h00;
                owPtr           <= #1 8'h00;
        end
        else begin
                wFull           <= #1 wFullD;
                wBusy           <= #1 wBusyD;
                iwPtr           <= #1 iwPtrD;
                owPtr           <= #1 owPtrD;
        end

assign wFullD           = (iwPtrD[7] != owPtrD[7]) & (iwPtrD[6:0] == owPtrD[6:0]);
assign wBusyD           = (iwPtrD != owPtrD);
assign iwPtrD           = iwPtr + iwAlloc;
assign owPtrD           = owPtr + owAlloc;

assign iwAlloc          = wrStrb & wrAck;

assign wrAck            = !wFull;

// -----------------------------------------------------------------------------
// Read Data
assign rdAck            = rBusy;

assign rdData           = rdFIFO[irPtr[6:0]];

assign irAlloc          = rdStrb & rdAck;

// -----------------------------------------------------------------------------
// Memory Write
always @(posedge clk)
        if (owAlloc)
                mem[oAddr[31:BLR+NLR]]
                        <= #1 {BL{owData}} & ~mask | mem[oAddr[31:BLR+NLR]] & mask;

always @(
        owMask or
        oMod
        )
        for (i=0; i<BL; i=i+1)
                for (j=0; j<NBL; j=j+1)
                        mask[NL*i+j]    = owMask[j/8] | (oMod[i] != i);

assign owData           = wdFIFO[owPtr[6:0]];
assign owMask           = wmFIFO[owPtr[6:0]];

assign owAlloc          = aBusy & !oRxw & wBusy;

// -----------------------------------------------------------------------------
// Memory Read
always @(posedge clk)
        if (orAlloc)
                rdFIFO[orPtr[6:0]]
                                <= #1 mem[oAddr[31:BLR+NLR]] >> {oMod, {NLR+3{1'b0}}};

always @(posedge clk)
        if (reset) begin
                rFull           <= #1 1'b0;
                rBusy           <= #1 1'b0;
                irPtr           <= #1 8'h00;
                orPtr           <= #1 8'h00;
        end
        else begin
                rFull           <= #1 rFullD;
                rBusy           <= #1 rBusyD;
                irPtr           <= #1 irPtrD;
                orPtr           <= #1 orPtrD;
        end

assign rFullD           = (irPtrD[7] != orPtrD[7]) & (irPtrD[6:0] == orPtrD[6:0]);
assign rBusyD           = (irPtrD != orPtrD);
assign irPtrD           = irPtr + irAlloc;
assign orPtrD           = orPtr + orAlloc;

assign orAlloc          = aBusy & !rFull & oRxw;

// **************************** FUNCTIONS and TASKS ****************************

endmodule

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

Logical Circuit Design > Test > Bus Slave    Next page(SRAM Model)   TOP of this page ▲