Exemplo n.º 1
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));
    }
}
Exemplo n.º 2
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);
    }
}
Exemplo n.º 3
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");
		}
	}
}