예제 #1
0
void CHtvDesign::SynHtDistRamWe(CHtvIdent *pHier, CHtvObject * pObj, CHtvObject * pRtnObj, CHtvOperand *pExpr, bool bIsAlwaysAt)
{
    // Synthesize a write enable assignment statement
    //   syntax is: variable = value
    //   write variable as single bit wide value per dist ram section

    CHtvIdent *pWeIdent = pExpr->GetOperand1()->GetMember();
    vector<CHtDistRamWeWidth> *pWeWidth = pWeIdent->GetHtDistRamWeWidth();

    if ( (*pWeWidth).size() == 1) {

        if (!bIsAlwaysAt)
            m_vFile.Print("assign ");

        bool bFoundSubExpr;
        bool bWriteIndex;
        FindSubExpr(pObj, pRtnObj, pExpr, bFoundSubExpr, bWriteIndex);

        if (!bWriteIndex) {
            PrintSubExpr(pObj, pRtnObj, pExpr);
            m_vFile.Print(";\n");
        }

        if (bFoundSubExpr) {
            m_vFile.DecIndentLevel();
            m_vFile.Print("end\n");
        }

    } else {

        int exprHighBit, exprLowBit;
        pExpr->GetOperand1()->GetDistRamWeWidth(exprHighBit, exprLowBit);

        CHtvIdent * pOp1Ident = pExpr->GetOperand1()->GetMember();
        string origIdent = pOp1Ident->GetName();

        for (size_t i = 0; i < (*pWeWidth).size(); i += 1) {
            int highBit = (*pWeWidth)[i].m_highBit;
            int lowBit = (*pWeWidth)[i].m_lowBit;

            if (!(exprLowBit < 0) && !(exprLowBit <= lowBit && highBit <= exprHighBit))
                continue;

            string weName = VA("%s_%d_%d", origIdent.c_str(), highBit, lowBit);
            pOp1Ident->SetName(weName);

            if (!bIsAlwaysAt)
                m_vFile.Print("assign ");

            bool bFoundSubExpr;
            bool bWriteIndex;
            FindSubExpr(pObj, pRtnObj, pExpr, bFoundSubExpr, bWriteIndex);

            if (!bWriteIndex) {
                PrintSubExpr(pObj, pRtnObj, pExpr);
                m_vFile.Print(";\n");
            }

            if (bFoundSubExpr) {
                m_vFile.DecIndentLevel();
                m_vFile.Print("end\n");
            }
        }

        pOp1Ident->SetName(origIdent);
    }
}
예제 #2
0
void CHtvDesign::SynHtBlockQueRams(CHtvIdent *pHier)
{
    string inputFileName = g_htvArgs.GetInputFileName();

    CHtvIdentTblIter identIter(pHier->GetFlatIdentTbl());
    for (identIter.Begin(); !identIter.End(); identIter++) {
        if (!identIter->IsVariable() || !identIter->IsHtBlockQue())
            continue;

        CHtvIdent *pQueueRam = identIter();
        m_bIs1CkHtBlockRamsPresent = true;

        // Block Ram
        int addrWidth = pQueueRam->GetType()->GetHtMemoryAddrWidth1();
        addrWidth += pQueueRam->GetType()->GetHtMemoryAddrWidth2();

        string cQueName = pQueueRam->GetName();
        if (cQueName.substr(0,2) == "r_" || cQueName.substr(0,2) == "m_")
            cQueName.replace(0, 2, "c_");
        else
            cQueName.insert(0, "c_");

        string rQueName = pQueueRam->GetName();
        if (rQueName.substr(0,2) == "m_")
            rQueName.replace(0, 2, "r_");

        vector<int> refList(pQueueRam->GetDimenCnt(), 0);

        char buf[128];
        do {
            string refDimStr;
            string modDimStr;

            for (size_t i = 0; i < refList.size(); i += 1) {
                sprintf(buf, "$%d", refList[i]);
                refDimStr += buf;

                sprintf(buf, "$%d", refList[i]);
                modDimStr += buf;
            }

            if (pQueueRam->GetType()->IsHtBlockRamDoReg())
                m_vFile.Print("\n%s_HtBlockRam1CkDoReg #( .DATA_WIDTH(%d), .ADDR_WIDTH(%d) ) %s%s ( ",
                              inputFileName.c_str(), pQueueRam->GetWidth(), addrWidth, pQueueRam->GetName().c_str(), modDimStr.c_str());
            else
                m_vFile.Print("\n%s_HtBlockRam1Ck #( .DATA_WIDTH(%d), .ADDR_WIDTH(%d) ) %s%s ( ",
                              inputFileName.c_str(), pQueueRam->GetWidth(), addrWidth, pQueueRam->GetName().c_str(), modDimStr.c_str());

            bool bMultiple;
            CHtvIdent * pMethod = FindUniqueAccessMethod(&pQueueRam->GetHierIdent()->GetWriterList(), bMultiple);

            if (bMultiple)
                ParseMsg(PARSE_FATAL, pQueueRam->GetLineInfo(), "ht_queue push by muliple methods");

            m_vFile.Print(".clk( %s ), ", pMethod->GetClockIdent()->GetName().c_str());
            m_vFile.Print(".we( %s_WrEn%s ), ", cQueName.c_str(), refDimStr.c_str());
            m_vFile.Print(".wa( %s_WrAddr%s[%d:0] ), ", rQueName.c_str(), refDimStr.c_str(), addrWidth-1);
            m_vFile.Print(".din( %s_WrData%s ), ", cQueName.c_str(), refDimStr.c_str());
            m_vFile.Print(".ra( %s_RdAddr%s[%d:0] ), ", cQueName.c_str(), refDimStr.c_str(), addrWidth-1);
            m_vFile.Print(".dout( %s_RdData%s ) );\n", cQueName.c_str(), refDimStr.c_str());

        } while (!pQueueRam->DimenIter(refList));
    }
}
예제 #3
0
void CHtvDesign::SynHtDistRams(CHtvIdent *pHier)
{
    string inputFileName = g_htvArgs.GetInputFileName();

    CHtvIdentTblIter identIter(pHier->GetFlatIdentTbl());
    for (identIter.Begin(); !identIter.End(); identIter++) {
        if (!identIter->IsVariable() || !identIter->IsHtMemory())
            continue;

        if (identIter->IsHtBlockRam() || identIter->IsHtMrdBlockRam() || identIter->IsHtMwrBlockRam() || identIter->IsHtQueue())
            continue;

        CHtvIdent *pDistRam = identIter();
        m_bIsHtDistRamsPresent = true;

        int addrWidth = pDistRam->GetType()->GetHtMemoryAddrWidth1();
        addrWidth += pDistRam->GetType()->GetHtMemoryAddrWidth2();

        vector<CHtDistRamWeWidth> *pWeWidth = pDistRam->GetHtDistRamWeWidth();

        for (size_t j = 0; j < pWeWidth->size(); j += 1) {
            int highBit = (*pWeWidth)[j].m_highBit;
            int lowBit = (*pWeWidth)[j].m_lowBit;

            size_t i;
            for (i = 0; i < m_htDistRamTypes.size(); i += 1) {
                if (m_htDistRamTypes[i].m_addrWidth == addrWidth &&
                        m_htDistRamTypes[i].m_dataWidth == highBit-lowBit+1)
                    break;
            }

            if (i == m_htDistRamTypes.size())
                m_htDistRamTypes.push_back(CHtDistRamType(addrWidth, highBit-lowBit+1));
        }

        string cQueName = pDistRam->GetName();
        if (cQueName.substr(0,2) == "r_" || cQueName.substr(0,2) == "m_")
            cQueName.replace(0, 2, "c_");
        else
            cQueName.insert(0, "c_");

        bool bMultiple;
        CHtvIdent * pMethod = FindUniqueAccessMethod(&pDistRam->GetHierIdent()->GetWriterList(), bMultiple);

        if (bMultiple)
            ParseMsg(PARSE_FATAL, pDistRam->GetLineInfo(), "ht_queue push by muliple methods");

        CHtvIdent *pClockIdent = pMethod->GetClockIdent();

        vector<int> refList(pDistRam->GetDimenCnt(), 0);

        char buf[128];
        do {
            string refDimStr;
            string modDimStr;

            for (size_t i = 0; i < refList.size(); i += 1) {
                sprintf(buf, "$%d", refList[i]);
                refDimStr += buf;

                sprintf(buf, "$%d", refList[i]);
                modDimStr += buf;
            }

            if (pWeWidth->size() == 1) {
                m_vFile.Print("\n%s_HtDistRam #( .DATA_WIDTH(%d), .ADDR_WIDTH(%d) ) %s%s ( ",
                              inputFileName.c_str(), pDistRam->GetWidth(), addrWidth, pDistRam->GetName().c_str(), modDimStr.c_str());

                m_vFile.Print(".clk( %s ), ", pClockIdent->GetName().c_str());
                m_vFile.Print(".we( %s_WrEn%s ), ", cQueName.c_str(), refDimStr.c_str());
                m_vFile.Print(".wa( %s_WrAddr%s ), ", cQueName.c_str(), refDimStr.c_str());
                m_vFile.Print(".din( %s_WrData%s ), ", cQueName.c_str(), refDimStr.c_str());
                m_vFile.Print(".ra( %s_RdAddr%s ), ", cQueName.c_str(), refDimStr.c_str());
                m_vFile.Print(".dout( %s_RdData%s ) );\n", cQueName.c_str(), refDimStr.c_str());

            } else {
                for (size_t j = 0; j < pWeWidth->size(); j += 1) {
                    int highBit = (*pWeWidth)[j].m_highBit;
                    int lowBit = (*pWeWidth)[j].m_lowBit;

                    m_vFile.Print("\n%s_HtDistRam #( .DATA_WIDTH(%d), .ADDR_WIDTH(%d) ) %s%s_%d_%d ( ",
                                  inputFileName.c_str(), highBit-lowBit+1, addrWidth,
                                  pDistRam->GetName().c_str(), modDimStr.c_str(), highBit, lowBit);

                    m_vFile.Print(".clk( %s ), ", pClockIdent->GetName().c_str());
                    m_vFile.Print(".we( %s_WrEn_%d_%d%s ), ", cQueName.c_str(), highBit, lowBit, refDimStr.c_str());
                    m_vFile.Print(".wa( %s_WrAddr%s ), ", cQueName.c_str(), refDimStr.c_str());
                    m_vFile.Print(".din( %s_WrData%s[%d:%d] ), ", cQueName.c_str(), refDimStr.c_str(), highBit, lowBit);
                    m_vFile.Print(".ra( %s_RdAddr%s ), ", cQueName.c_str(), refDimStr.c_str());
                    m_vFile.Print(".dout( %s_RdData%s[%d:%d] ) );\n", cQueName.c_str(), refDimStr.c_str(), highBit, lowBit);
                }
            }

        } while (!pDistRam->DimenIter(refList));
    }
}
예제 #4
0
void CHtvDesign::SynHtAsymBlockRams(CHtvIdent *pHier)
{
    string inputFileName = g_htvArgs.GetInputFileName();

    CHtvIdentTblIter identIter(pHier->GetFlatIdentTbl());
    for (identIter.Begin(); !identIter.End(); identIter++) {
        if (!identIter->IsVariable() || (!identIter->IsHtQueue() && !identIter->IsHtMemory()))
            continue;

        if (!identIter->IsHtMrdBlockRam() && !identIter->IsHtMwrBlockRam())
            continue;

        CHtvIdent *pBlockRam = identIter();

        // Block Ram
        int addrWidth = pBlockRam->GetType()->GetHtMemoryAddrWidth1();
        addrWidth += pBlockRam->GetType()->GetHtMemoryAddrWidth2();

        int selWidth = pBlockRam->GetType()->GetHtMemorySelWidth();

        int dataWidth = pBlockRam->GetType()->GetType()->GetWidth();

        string cQueName = pBlockRam->GetName();
        if (cQueName.substr(0,2) == "r_" || cQueName.substr(0,2) == "m_")
            cQueName.replace(0, 2, "c_");
        else
            cQueName.insert(0, "c_");

        vector<int> refList(pBlockRam->GetDimenCnt(), 0);

        char buf[128];
        do {
            string refDimStr;
            string modDimStr;

            for (size_t i = 0; i < refList.size(); i += 1) {
                sprintf(buf, "$%d", refList[i]);
                refDimStr += buf;

                sprintf(buf, "$%d", refList[i]);
                modDimStr += buf;
            }

            bool bMultiple;
            CHtvIdent * pWriteMethod = FindUniqueAccessMethod(&pBlockRam->GetHierIdent()->GetWriterList(), bMultiple);

            if (bMultiple)
                ParseMsg(PARSE_FATAL, pBlockRam->GetLineInfo(), "ht_asym_block_ram write by muliple methods");

            CHtvIdent * pReadMethod = FindUniqueAccessMethod(&pBlockRam->GetHierIdent()->GetReaderList(), bMultiple);

            if (bMultiple)
                ParseMsg(PARSE_FATAL, pBlockRam->GetLineInfo(), "ht_asym_block_ram read by muliple methods");

            if (pReadMethod->GetClockIdent()->GetName() == pWriteMethod->GetClockIdent()->GetName()) {

                if (pBlockRam->GetType()->IsHtBlockRamDoReg()) {
                    if (identIter->IsHtMrdBlockRam()) {
                        m_bIs1CkDoRegHtMrdBlockRamsPresent = true;
                        m_vFile.Print("\n%s_HtBlockMrdRam1CkDoReg #( .DATA_W(%d), .ADDR_W(%d), .SEL_W(%d) ) %s%s ( ",
                                      inputFileName.c_str(), dataWidth, addrWidth, selWidth, pBlockRam->GetName().c_str(), modDimStr.c_str());
                    }
                    if (identIter->IsHtMwrBlockRam()) {
                        m_bIs1CkDoRegHtMwrBlockRamsPresent = true;
                        m_vFile.Print("\n%s_HtBlockMwrRam1CkDoReg #( .DATA_W(%d), .ADDR_W(%d), .SEL_W(%d) ) %s%s ( ",
                                      inputFileName.c_str(), dataWidth, addrWidth, selWidth, pBlockRam->GetName().c_str(), modDimStr.c_str());
                    }
                } else {
                    if (identIter->IsHtMrdBlockRam()) {
                        m_bIs1CkHtMrdBlockRamsPresent = true;
                        m_vFile.Print("\n%s_HtMrdBlockRam1Ck #( .DATA_W(%d), .ADDR_W(%d), .SEL_W(%d) ) %s%s ( ",
                                      inputFileName.c_str(), dataWidth, addrWidth, selWidth, pBlockRam->GetName().c_str(), modDimStr.c_str());
                    }
                    if (identIter->IsHtMwrBlockRam()) {
                        m_bIs1CkHtMwrBlockRamsPresent = true;
                        m_vFile.Print("\n%s_HtMwrBlockRam1Ck #( .DATA_W(%d), .ADDR_W(%d), .SEL_W(%d) ) %s%s ( ",
                                      inputFileName.c_str(), dataWidth, addrWidth, selWidth, pBlockRam->GetName().c_str(), modDimStr.c_str());
                    }
                }

                m_vFile.Print(".ck( %s ), ", pWriteMethod->GetClockIdent()->GetName().c_str());
            } else {
                if (pBlockRam->GetType()->IsHtBlockRamDoReg()) {
                    if (identIter->IsHtMrdBlockRam()) {
                        m_bIs2CkDoRegHtMrdBlockRamsPresent = true;
                        m_vFile.Print("\n%s_HtMrdBlockRam2CkDoReg #( .DATA_W(%d), .ADDR_W(%d), .SEL_W(%d) ) %s%s ( ",
                                      inputFileName.c_str(), dataWidth, addrWidth, selWidth, pBlockRam->GetName().c_str(), modDimStr.c_str());
                    }
                    if (identIter->IsHtMwrBlockRam()) {
                        m_bIs2CkDoRegHtMwrBlockRamsPresent = true;
                        m_vFile.Print("\n%s_HtMwrBlockRam2CkDoReg #( .DATA_W(%d), .ADDR_W(%d), .SEL_W(%d) ) %s%s ( ",
                                      inputFileName.c_str(), dataWidth, addrWidth, selWidth, pBlockRam->GetName().c_str(), modDimStr.c_str());
                    }
                } else {
                    if (identIter->IsHtMrdBlockRam()) {
                        m_bIs2CkHtMrdBlockRamsPresent = true;
                        m_vFile.Print("\n%s_HtMrdBlockRam2Ck #( .DATA_W(%d), .ADDR_W(%d), .SEL_W(%d) ) %s%s ( ",
                                      inputFileName.c_str(), dataWidth, addrWidth, selWidth, pBlockRam->GetName().c_str(), modDimStr.c_str());
                    }
                    if (identIter->IsHtMwrBlockRam()) {
                        m_bIs2CkHtMwrBlockRamsPresent = true;
                        m_vFile.Print("\n%s_HtMwrBlockRam2Ck #( .DATA_W(%d), .ADDR_W(%d), .SEL_W(%d) ) %s%s ( ",
                                      inputFileName.c_str(), dataWidth, addrWidth, selWidth, pBlockRam->GetName().c_str(), modDimStr.c_str());
                    }
                }
                m_vFile.Print(".rck( %s ), ", pReadMethod->GetClockIdent()->GetName().c_str());
                m_vFile.Print(".wck( %s ), ", pWriteMethod->GetClockIdent()->GetName().c_str());
            }

            m_vFile.Print(".we( %s_WrEn%s ), ", cQueName.c_str(), refDimStr.c_str());
            if (identIter->IsHtMrdBlockRam())
                m_vFile.Print(".ws( %s_WrSel%s ), ", cQueName.c_str(), refDimStr.c_str());
            m_vFile.Print(".wa( %s_WrAddr%s ), ", cQueName.c_str(), refDimStr.c_str());
            m_vFile.Print(".wd( %s_WrData%s ), ", cQueName.c_str(), refDimStr.c_str());
            if (identIter->IsHtMwrBlockRam())
                m_vFile.Print(".rs( %s_RdSel%s ), ", cQueName.c_str(), refDimStr.c_str());
            m_vFile.Print(".ra( %s_RdAddr%s ), ", cQueName.c_str(), refDimStr.c_str());
            m_vFile.Print(".rd( %s_RdData%s ) );\n", cQueName.c_str(), refDimStr.c_str());

        } while (!pBlockRam->DimenIter(refList));
    }
}
예제 #5
0
void CHtvDesign::SynHtDistRamWe(CHtvIdent *pHier, CHtvObject * pObj, CHtvObject * pRtnObj, CHtvOperand *pExpr, bool bIsAlwaysAt)
{
	// Synthesize a write enable assignment statement
	//   syntax is: variable = value
	//   write variable as single bit wide value per dist ram section

	if (!bIsAlwaysAt)
		m_vFile.Print("assign ");

	vector<CHtfeOperand *> &weIndexList = pExpr->GetOperand1()->GetIndexList();

	CHtvIdent *pWeIdent = pExpr->GetOperand1()->GetMember();
	vector<CHtDistRamWeWidth> *pWeWidth = pWeIdent->GetHtDistRamWeWidth();

	CHtvOperand *pOp2 = pExpr->GetOperand2();
	Assert(pOp2->IsConstValue());

	if ( (*pWeWidth).size() == 1) {

		bool bFoundSubExpr;
		bool bWriteIndex;
		FindSubExpr(pObj, pRtnObj, pExpr, bFoundSubExpr, bWriteIndex);

		if (!bWriteIndex) {
			PrintSubExpr(pObj, pRtnObj, pExpr);
			m_vFile.Print(";\n");
		}

		if (bFoundSubExpr) {
			m_vFile.DecIndentLevel();
			m_vFile.Print("end\n");
		}

	} else {

		int exprHighBit, exprLowBit;
		pExpr->GetOperand1()->GetDistRamWeWidth(exprHighBit, exprLowBit);

		for (size_t i = 0; i < (*pWeWidth).size(); i += 1) {
			int highBit = (*pWeWidth)[i].m_highBit;
			int lowBit = (*pWeWidth)[i].m_lowBit;

			if (!(exprLowBit < 0) && !(exprLowBit <= lowBit && highBit <= exprHighBit))
				continue;

			m_vFile.Print("%s_%d_%d", pWeIdent->GetName().c_str(), highBit, lowBit);

			for (size_t i = 0; i < weIndexList.size(); i += 1) {
				if (!weIndexList[i]->IsConstValue())
					ParseMsg(PARSE_FATAL, weIndexList[i]->GetLineInfo(), "Non-constant index not supported");
				m_vFile.Print("$%d", weIndexList[i]->GetConstValue().GetSint32());
			}

			m_vFile.Print(" = ");

			if (pOp2->IsScX())
				m_vFile.Print("1'bx;\n");
			else if (pOp2->GetConstValue().GetUint64() == 0)
				m_vFile.Print("1'b0;\n");
			else
				m_vFile.Print("1'b1;\n");
		}
	}
}