/* ** HDL4SE: 软件Verilog综合仿真平台 ** Copyright (C) 2021-2021, raoxianhong ** LCOM: 轻量级组件对象模型 ** Copyright (C) 2021-2021, raoxianhong ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are met: ** ** * Redistributions of source code must retain the above copyright notice, ** this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright notice, ** this list of conditions and the following disclaimer in the documentation ** and/or other materials provided with the distribution. ** * The name of the author may be used to endorse or promote products ** derived from this software without specific prior written permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF ** THE POSSIBILITY OF SUCH DAMAGE. */ /* * hdl4se_mux16.c 修改记录: 202105180851: rxh, initial version 202105241522:rxh, 增加Detector接口 */ #include "stdlib.h" #include "stdio.h" #include "string.h" #include "object.h" #include "dlist.h" #include "bignumber.h" #include "hdl4secell.h" /* HDL4SE_MUX16 instance parameter: "8", width=8 */ #define MUXSELW 4 #define MUXCOUNT (1 << MUXSELW) typedef struct _sHDL4SEMux16 { OBJECT_HEADER INTERFACE_DECLARE(IHDL4SEUnit) HDL4SEUNIT_VARDECLARE INTERFACE_DECLARE(IHDL4SEDetector) HDL4SEDETECTOR_VARDECLARE DLIST_VARDECLARE IHDL4SEModule** parent; char* name; IHDL4SEUnit** sel; int sel_index; IHDL4SEUnit** in[MUXCOUNT]; int in_index[MUXCOUNT]; IBigNumber** in_sel; IBigNumber** out_data; int datavalid; int width; }sHDL4SEMux16; OBJECT_FUNCDECLARE(hdl4se_mux16, CLSID_HDL4SE_MUX16); HDL4SEUNIT_FUNCDECLARE(hdl4se_mux16, CLSID_HDL4SE_MUX16, sHDL4SEMux16); HDL4SEDETECTOR_FUNCDECLARE(hdl4se_mux16, CLSID_HDL4SE_MUX16, sHDL4SEMux16); DLIST_FUNCIMPL(hdl4se_mux16, CLSID_HDL4SE_MUX16, sHDL4SEMux16); OBJECT_FUNCIMPL(hdl4se_mux16, sHDL4SEMux16, CLSID_HDL4SE_MUX16); QUERYINTERFACE_BEGIN(hdl4se_mux16, CLSID_HDL4SE_MUX16) QUERYINTERFACE_ITEM(IID_HDL4SEUNIT, IHDL4SEUnit, sHDL4SEMux16) QUERYINTERFACE_ITEM(IID_HDL4SEDETECTOR, IHDL4SEDetector, sHDL4SEMux16) QUERYINTERFACE_ITEM(IID_DLIST, IDList, sHDL4SEMux16) QUERYINTERFACE_END static const char* hdl4se_mux16ModuleInfo() { return "1.0.0-20210521.1415 HDL4Se Mux16 cell"; } static int hdl4se_mux16Create(const PARAMITEM* pParams, int paramcount, HOBJECT* pObject) { sHDL4SEMux16* pobj; int i; pobj = (sHDL4SEMux16*)malloc(sizeof(sHDL4SEMux16)); if (pobj == NULL) return -1; *pObject = 0; HDL4SEUNIT_VARINIT(pobj, CLSID_HDL4SE_MUX16); INTERFACE_INIT(IHDL4SEUnit, pobj, hdl4se_mux16, hdl4se_unit); INTERFACE_INIT(IHDL4SEDetector, pobj, hdl4se_mux16, hdl4se_detector); DLIST_VARINIT(pobj, hdl4se_mux16); pobj->sel = NULL; pobj->sel_index = 0; for (i = 0; i < MUXCOUNT; i++) { pobj->in[i] = NULL; pobj->in_index[i] = 0; } pobj->in_sel = NULL; pobj->out_data = NULL; pobj->name = NULL; pobj->width = 8; pobj->datavalid = 0; pobj->parent = NULL; for (i = 0; i < paramcount; i++) { if (pParams[i].name == PARAMID_HDL4SE_UNIT_NAME) { if (pobj->name != NULL) free(pobj->name); pobj->name = strdup(pParams[i].pvalue); } else if (pParams[i].name == PARAMID_HDL4SE_UNIT_PARENT) { pobj->parent = (IHDL4SEModule **)pParams[i].pvalue; } else if (pParams[i].name == PARAMID_HDL4SE_UNIT_INSTANCE_PARAMETERS) { IBigNumber** temp = bigintegerCreate(32); if (temp != NULL) { const char* nstr; if (0 == objectCall2(temp, AssignStr, (const char*)pParams[i].pvalue, &nstr)) { objectCall1(temp, GetInt, &pobj->width); } objectRelease(temp); } } } if (pobj->width <= 0) return EIID_INVALIDPARAM; pobj->in_sel = bigintegerCreate(MUXSELW); pobj->out_data = bigintegerCreate(pobj->width); /* 返回生成的对象 */ OBJECT_RETURN_GEN(hdl4se_mux16, pobj, pObject, CLSID_HDL4SE_MUX16); return EIID_OK; } static void hdl4se_mux16Destroy(HOBJECT object) { sHDL4SEMux16* pobj; int i; pobj = (sHDL4SEMux16*)objectThis(object); if (pobj->name != NULL) free(pobj->name); objectRelease(pobj->sel); for (i = 0; i < MUXCOUNT; i++) { objectRelease(pobj->in[i]); } objectRelease(pobj->in_sel); objectRelease(pobj->out_data); memset(pobj, 0, sizeof(sHDL4SEMux16)); free(pobj); } static int hdl4se_mux16Valid(HOBJECT object) { sHDL4SEMux16* pobj; pobj = (sHDL4SEMux16*)objectThis(object); return 1; } static int hdl4se_mux16_hdl4se_unit_Connect(HOBJECT object, int index, HOBJECT from, int fromindex) { sHDL4SEMux16* pobj; IHDL4SEUnit** unit = NULL; pobj = (sHDL4SEMux16*)objectThis(object); if (index == 0) { if (0 == objectQueryInterface(from, IID_HDL4SEUNIT, (void**)&unit)) { objectRelease(pobj->sel); pobj->sel = unit; pobj->sel_index = fromindex; } else { return -2; } } else if (index >= 1 && index <= MUXCOUNT) { if (0 == objectQueryInterface(from, IID_HDL4SEUNIT, (void**)&unit)) { objectRelease(pobj->in[index-1]); pobj->in[index-1] = unit; pobj->in_index[index-1] = fromindex; } else { return -2; } } else { return -1; } return 0; } static int hdl4se_mux16_hdl4se_unit_GetValue(HOBJECT object, int index, int width, IBigNumber ** value) { int sel; sHDL4SEMux16* pobj; pobj = (sHDL4SEMux16*)objectThis(object); if (pobj->datavalid == 0) { objectCall3(pobj->sel, GetValue, pobj->sel_index, MUXSELW, pobj->in_sel); objectCall2(pobj->in_sel, SetWidth, MUXSELW, 0); objectCall1(pobj->in_sel, GetInt, &sel); sel &= MUXCOUNT - 1; if (sel >= 0 && sel < MUXCOUNT) { objectCall3(pobj->in[sel], GetValue, pobj->in_index[sel], pobj->width, pobj->out_data); } else { return -2; } pobj->datavalid = 1; } objectCall1(value, Assign, pobj->out_data); return 0; } static int hdl4se_mux16_hdl4se_unit_ClkTick(HOBJECT object) { sHDL4SEMux16* pobj; pobj = (sHDL4SEMux16*)objectThis(object); return 0; } static int hdl4se_mux16_hdl4se_unit_Setup(HOBJECT object) { sHDL4SEMux16* pobj; pobj = (sHDL4SEMux16*)objectThis(object); pobj->datavalid = 0; return 0; } static int hdl4se_mux16_hdl4se_detector_GetName(HOBJECT object, const char** pname) { sHDL4SEMux16* pobj; pobj = (sHDL4SEMux16*)objectThis(object); *pname = pobj->name; return 0; } static int hdl4se_mux16_hdl4se_detector_GetSignalCount(HOBJECT object) { sHDL4SEMux16* pobj; pobj = (sHDL4SEMux16*)objectThis(object); return 1; } static int hdl4se_mux16_hdl4se_detector_GetSignalInfo(HOBJECT object, int index, const char** pname, int *width) { sHDL4SEMux16* pobj; pobj = (sHDL4SEMux16*)objectThis(object); *pname = "out"; *width = pobj->width; return 0; } static int hdl4se_mux16_hdl4se_detector_GetSignalValue(HOBJECT object, int index, IBigNumber** value) { sHDL4SEMux16* pobj; pobj = (sHDL4SEMux16*)objectThis(object); return hdl4se_mux16_hdl4se_unit_GetValue(object, 0, pobj->width, value); } static int hdl4se_mux16_hdl4se_detector_GetUnitCount(HOBJECT object) { sHDL4SEMux16* pobj; pobj = (sHDL4SEMux16*)objectThis(object); return 0; } static int hdl4se_mux16_hdl4se_detector_GetUnit(HOBJECT object, int index, HOBJECT* unit) { sHDL4SEMux16* pobj; pobj = (sHDL4SEMux16*)objectThis(object); return 0; }