diff --git a/examples/terris/CMakeLists.txt b/examples/terris/CMakeLists.txt index ea37c2605b022ae5f9648bb9ab7a39a522b0f672..07be7ed4d9f632cb61704b5456e3a127ea78167b 100644 --- a/examples/terris/CMakeLists.txt +++ b/examples/terris/CMakeLists.txt @@ -9,7 +9,12 @@ add_executable (terris "src/main.c" "glad/src/gl.c" "glad/include/KHR/khrplatform.h" - "glad/include/glad/gl.h" "src/topmodule.c" "src/terisctrl.c" "src/topmodule2.c") + "glad/include/glad/gl.h" + "src/topmodule.c" + "src/topmodule2.c" + "src/terisctrl_2.c" + "src/terisctrl.c" + "include/terrisengine2.h") target_link_libraries(terris hdl4sesim hdl4secell bignumber digitled hdl4seutils verilog_parser glui glfw lcom) diff --git a/examples/terris/include/terris.h b/examples/terris/include/terris.h index 1336a8c819fee4470660e3c08319f86575db588e..10484ae00ec7707024a3493e138dbe1dbff758d9 100644 --- a/examples/terris/include/terris.h +++ b/examples/terris/include/terris.h @@ -47,6 +47,8 @@ extern "C" { DEFINE_GUID(CLSID_TERRISDEVICE, 0x81de7969, 0xf783, 0x4023, 0xbd, 0xe6, 0xf8, 0x15, 0xf8, 0xd5, 0x9c, 0x5); DEFINE_GUID(CLSID_TERRISCTRL, 0x6f8a9aa6, 0xec57, 0x4734, 0xa1, 0x83, 0x78, 0x71, 0xed, 0x57, 0xea, 0x95); +DEFINE_GUID(CLSID_TERRISCTRL2, 0x9d063daf, 0xa778, 0x4652, 0xa6, 0xcb, 0xa8, 0xa6, 0xec, 0x56, 0x90, 0x44); + DEFINE_GUID(PARAMID_BASEADDR,0x55faed75, 0xefbe, 0x461d, 0x81, 0x99, 0x90, 0x58, 0x88, 0xab, 0x47, 0x93); diff --git a/examples/terris/include/terrisengine.h b/examples/terris/include/terrisengine.h index ad14b104425372414446c9f0a2ba994757eeadcf..93478c0940ff574a65cd7c5f1c0b948bb6f224e4 100644 --- a/examples/terris/include/terrisengine.h +++ b/examples/terris/include/terrisengine.h @@ -22,7 +22,7 @@ enum TERRIS_KEY { #define LEVEL 2 /*块的形状*/ -const unsigned long blockshape[][4][4] = +static const unsigned long blockshape[][4][4] = { { {0,0,0,0}, @@ -393,6 +393,7 @@ static void terrisPressKey(int key) gameScore--; break; } + currenttick = 0; if (gameScore < 0) terrisInit(); } diff --git a/examples/terris/include/terrisengine2.h b/examples/terris/include/terrisengine2.h new file mode 100644 index 0000000000000000000000000000000000000000..93478c0940ff574a65cd7c5f1c0b948bb6f224e4 --- /dev/null +++ b/examples/terris/include/terrisengine2.h @@ -0,0 +1,400 @@ + + +#include "stdio.h" +#include "stdlib.h" +#include "string.h" +#include "time.h" + +enum TERRIS_KEY { + TK_LEFT, + TK_DOWN, + TK_RIGHT, + TK_TURNLEFT, + TK_TURNRIGHT +}; + +#define PANELWIDTH XCOUNT +#define PANELHEIGHT YCOUNT +#define PANELGAP 0 +#define BLOCKSIZE 4 + +#define BLOCKSHAPES (sizeof(blockshape) / (sizeof(unsigned long) * 16)) + +#define LEVEL 2 +/*块的形状*/ +static const unsigned long blockshape[][4][4] = +{ + { + {0,0,0,0}, + {0,1,1,0}, + {0,1,1,0}, + {0,0,0,0}, + }, +#if LEVEL > 1 + { + {1,1,1,0}, + {1,1,1,0}, + {1,1,1,0}, + {0,0,0,0}, + }, +#endif + /* 变态*/ +#if LEVEL > 3 + { + {1,0,0,1}, + {1,1,1,1}, + {1,1,1,1}, + {1,0,0,1}, + }, +#endif + /* 变态*/ +#if LEVEL > 3 + { + {1,0,0,1}, + {0,1,1,0}, + {0,1,1,0}, + {1,0,0,1}, + }, +#endif +#if LEVEL > 2 + { + {1,1,1,1}, + {1,1,1,1}, + {1,1,1,1}, + {1,1,1,1}, + }, +#endif + { + {0,0,0,0}, + {0,1,1,0}, + {0,0,1,0}, + {0,0,0,0}, + }, + { + {0,0,0,0}, + {0,1,0,0}, + {0,0,1,0}, + {0,0,0,0}, + }, +/* 难 */ +#if LEVEL > 2 + { + {0,1,0,0}, + {1,1,1,0}, + {0,1,0,0}, + {0,0,0,0}, + }, +#endif + { + {0,1,0,0}, + {0,1,0,0}, + {0,1,0,0}, + {0,1,0,0}, + }, +/* 难*/ +#if LEVEL > 2 + { + {0,0,0,0}, + {1,0,0,1}, + {1,1,1,1}, + {0,0,0,0}, + }, +#endif +/* 变态*/ +#if LEVEL > 3 + { + {1,0,1,0}, + {0,1,0,0}, + {1,0,1,0}, + {0,0,0,0}, + }, +#endif + +#if LEVEL > 1 + { + {0,1,0,0}, + {0,1,1,0}, + {0,0,1,0}, + {0,0,0,0}, + }, + { + {0,0,1,0}, + {0,1,1,0}, + {0,1,0,0}, + {0,0,0,0}, + }, +#endif + { + {0,0,0,0}, + {0,1,0,0}, + {1,1,1,0}, + {0,0,0,0}, + }, + { + {0,0,0,0}, + {0,1,0,0}, + {0,0,0,0}, + {0,0,0,0}, + }, + { + {0,1,1,0}, + {0,0,1,0}, + {0,0,1,0}, + {0,0,0,0}, + }, + { + {0,1,1,0}, + {0,1,0,0}, + {0,1,0,0}, + {0,0,0,0}, + }, +}; + + +typedef struct tagTerrisBlock +{ + int posx, posy; + unsigned long subblock[BLOCKSIZE][BLOCKSIZE]; +}TerrisBlock; + +#define MAXSPPED 6000 +static int gameScore = 0; +static int currentspeed = MAXSPPED; +static int gameLevel = 0; +static int currenttick = 0; +static TerrisBlock currentblock, nextblock; +static unsigned long terrisPanel[PANELHEIGHT][PANELWIDTH]; + +static int terrisBlockCanSetTo(TerrisBlock * pBlock, int x, int y); +static int terrisGenNewBlock(TerrisBlock * pBlock); + +static void terrisInit() +{ + int i, j; + /*初始化并开始*/ + srand( (unsigned)time( NULL ) ); + memset((char *)terrisPanel, 0, sizeof(terrisPanel)); + currentspeed = MAXSPPED; + currenttick = 0; + gameScore = 200; + gameLevel = 0; + + /*边沿*/ + for (i = 0;isubblock[BLOCKSIZE-1-j][i]; + else + paneltemp[i][j] = pBlock->subblock[j][BLOCKSIZE-1-i]; + } + memcpy(pBlock->subblock, paneltemp, sizeof(paneltemp)); +} + +static int terrisBlockCanSetTo(TerrisBlock * pBlock, int x, int y) +{ + int i; + int j; + for (i = 0;isubblock[i][j] != 0) + { + int xx, yy; + xx = x - BLOCKSIZE / 2 + j; + yy = y - BLOCKSIZE / 2 + i; + if (yy < 0) + continue; + if (yy >= PANELHEIGHT) + return 0; + if (xx < 0) + return 0; + if (xx >= PANELWIDTH) + return 0; + if (terrisPanel[yy][xx] != 0) + return 0; + } + } + return 1; +} + +static int terrisCheckLine() +{ + int i; + int j; + int totallines; + totallines = 0; + for (i = 0;i0;k--) + { + for (j = 0;jposx = PANELWIDTH / 2; + pBlock->posy = 0; + shape = rand() % BLOCKSHAPES; + for (i = 0;isubblock[i][j] = color; + } + return terrisBlockCanSetTo(pBlock, pBlock->posx, pBlock->posy); +} + +static void terrisDown() +{ + if (terrisBlockCanSetTo(¤tblock, currentblock.posx, currentblock.posy+1)) + { + currentblock.posy ++; + } + else + { + int i; + int j; + for (i = 0;i= PANELHEIGHT) + continue; + if (xx < 0) + continue; + if (xx >= PANELWIDTH) + continue; + if (terrisPanel[yy][xx] != 0) + continue; + terrisPanel[yy][xx] = currentblock.subblock[i][j]; + } + } + } + terrisCheckLine(); + memcpy(¤tblock, &nextblock, sizeof(currentblock)); + if (terrisGenNewBlock(&nextblock) == 0) + { + terrisInit(); + } + } +} + +static int terrisTick() +{ + currenttick++; + if ((currenttick % currentspeed) == 0) + { + terrisDown(); + return 1; + } + return 0; +} + +static void terrisPressKey(int key) +{ + switch (key) + { + case TK_LEFT:/*left*/ + if (terrisBlockCanSetTo(¤tblock, currentblock.posx - 1, currentblock.posy)) + currentblock.posx--; + gameScore--; + break; + case TK_DOWN:/*down*/ + gameScore += 2; + terrisDown(); + break; + case TK_RIGHT:/*right*/ + if (terrisBlockCanSetTo(¤tblock, currentblock.posx + 1, currentblock.posy)) + currentblock.posx++; + gameScore--; + break; + case TK_TURNLEFT:/*逆时针1*/ + terrisBlockRotate(¤tblock, 1); + if (terrisBlockCanSetTo(¤tblock, currentblock.posx, currentblock.posy)==0) + terrisBlockRotate(¤tblock, 0); + gameScore--; + break; + case TK_TURNRIGHT:/*顺时针0*/ + terrisBlockRotate(¤tblock, 0); + if (terrisBlockCanSetTo(¤tblock, currentblock.posx, currentblock.posy)==0) + terrisBlockRotate(¤tblock, 1); + gameScore--; + break; + } + currenttick = 0; + if (gameScore < 0) + terrisInit(); +} + diff --git a/examples/terris/src/main.c b/examples/terris/src/main.c index 9f6da17a50bc243893c5408ee077da549542f044..4a3222c7eaedf67b0025a118ac6f1cd0f75149af 100644 --- a/examples/terris/src/main.c +++ b/examples/terris/src/main.c @@ -59,6 +59,7 @@ int StopRunning() IHDL4SEUnit** hdl4seCreate_main(IHDL4SEModule** parent, const char* instanceparam, const char* name); IHDL4SEUnit** hdl4seCreate_main2(IHDL4SEModule** parent, const char* instanceparam, const char* name); extern int (*A_u_t_o_registor_terrisctrl)(); +extern int (*A_u_t_o_registor_terrisctrl2)(); int main(int argc, char* argv[]) { @@ -68,6 +69,7 @@ int main(int argc, char* argv[]) IHDL4SEUnit** sim_unit; IHDL4SEWaveOutput** vcdfile; A_u_t_o_registor_terrisctrl(); + A_u_t_o_registor_terrisctrl2(); sim = hdl4sesimCreateSimulator(); topmodule = hdl4seCreate_main(NULL, "", "main"); gui = guiCreate(0xf0000000, "terris"); diff --git a/examples/terris/src/terisctrl.c b/examples/terris/src/terisctrl.c index 5f16a359cf6d666955b4f07df1b9255578352762..014da7500c074f73ac28035d6bf828203455b4bb 100644 --- a/examples/terris/src/terisctrl.c +++ b/examples/terris/src/terisctrl.c @@ -145,7 +145,7 @@ static int terrisctrl_hdl4se_unit_Connect(HOBJECT object, int index, HOBJECT fro sTerrisCtrl* pobj; IHDL4SEUnit** unit = NULL; pobj = (sTerrisCtrl*)objectThis(object); - if (index == 4) { + if (index == 5) { if (0 == objectQueryInterface(from, IID_HDL4SEUNIT, (void**)&unit)) { objectRelease(pobj->readdata_unit); pobj->readdata_unit = unit; @@ -169,9 +169,13 @@ static int terrisctrl_hdl4se_unit_GetValue(HOBJECT object, int index, int width, sTerrisCtrl* pobj; pobj = (sTerrisCtrl*)objectThis(object); if (index == 2) { + objectCall1(value, AssignUint32, 1); + } + else + if (index == 3) { objectCall1(value, AssignUint32, pobj->writeaddr); } - else if (index == 3) { + else if (index == 4) { objectCall1(value, AssignUint32, pobj->writedata); } return 0; @@ -234,11 +238,11 @@ static int terrisctrl_hdl4se_unit_Setup(HOBJECT object) pobj = (sTerrisCtrl*)objectThis(object); /* 每个周期更新半行 */ if (pobj->currentline >= 0 && pobj->currentline < YCOUNT * 2) { - pobj->writeaddr = 0xF0000010 + pobj->currentline * 4; + pobj->writeaddr = 0x10 + pobj->currentline * 4; pobj->writedata = get_line_data(pobj, pobj->currentline / 2, pobj->currentline & 1); } else if (pobj->currentline == YCOUNT * 2 + 0) { - pobj->writeaddr = 0xF00000e0; + pobj->writeaddr = 0xe0; pobj->writedata = ((nextblock.subblock[0][0] & 0xf) << 0) | ((nextblock.subblock[0][1] & 0xf) << 4) @@ -251,7 +255,7 @@ static int terrisctrl_hdl4se_unit_Setup(HOBJECT object) ; } else if (pobj->currentline == YCOUNT * 2 + 1) { - pobj->writeaddr = 0xF00000e4; + pobj->writeaddr = 0xe4; pobj->writedata = ((nextblock.subblock[2][0] & 0xf) << 0) | ((nextblock.subblock[2][1] & 0xf) << 4) @@ -264,15 +268,15 @@ static int terrisctrl_hdl4se_unit_Setup(HOBJECT object) ; } else if (pobj->currentline == YCOUNT * 2 + 2) { - pobj->writeaddr = 0xF00000f0; + pobj->writeaddr = 0xf0; pobj->writedata = gameScore; } else if (pobj->currentline == YCOUNT * 2 + 3) { - pobj->writeaddr = 0xF00000f4; + pobj->writeaddr = 0xf4; pobj->writedata = gameLevel; } else if (pobj->currentline == YCOUNT * 2 + 4) { - pobj->writeaddr = 0xF00000f8; + pobj->writeaddr = 0xf8; pobj->writedata = MAXSPPED - currentspeed; } pobj->currentline = pobj->currentline + 1; diff --git a/examples/terris/src/terisctrl_2.c b/examples/terris/src/terisctrl_2.c new file mode 100644 index 0000000000000000000000000000000000000000..57215a15487620508da270c6d5cdc60e98fc9a17 --- /dev/null +++ b/examples/terris/src/terisctrl_2.c @@ -0,0 +1,364 @@ +/* +** 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. +*/ + +/* +* terisctrl_2.c + 修改记录: + 202106171949: rxh, initial version +*/ +#include "stdlib.h" +#include "stdio.h" +#include "string.h" +#include "object.h" +#include "dlist.h" +#include "bignumber.h" +#include "hdl4secell.h" +#include "terris.h" +#include "terrisengine2.h" + + +typedef struct _sTerrisCtrl2 { + OBJECT_HEADER + INTERFACE_DECLARE(IHDL4SEUnit) + HDL4SEUNIT_VARDECLARE + INTERFACE_DECLARE(IHDL4SEDetector) + HDL4SEDETECTOR_VARDECLARE + DLIST_VARDECLARE + + IHDL4SEModule** parent; + char* name; + + IHDL4SEUnit** readdata_unit; + int readdata_index; + IBigNumber** readdata; + IBigNumber** lastreaddata; + + IHDL4SEUnit** readdata_unit1; + int readdata_index1; + IBigNumber** readdata1; + IBigNumber** lastreaddata1; + + unsigned int write; + unsigned int writeaddr; + unsigned int writedata; + unsigned int write1; + unsigned int writeaddr1; + unsigned int writedata1; + unsigned int readaddr1; + + int currentline; + +}sTerrisCtrl2; + +OBJECT_FUNCDECLARE(terrisctrl2, CLSID_TERRISCTRL2); +HDL4SEUNIT_FUNCDECLARE(terrisctrl2, CLSID_TERRISCTRL2, sTerrisCtrl2); +HDL4SEDETECTOR_FUNCDECLARE(terrisctrl2, CLSID_TERRISCTRL2, sTerrisCtrl2); +DLIST_FUNCIMPL(terrisctrl2, CLSID_TERRISCTRL2, sTerrisCtrl2); + +OBJECT_FUNCIMPL(terrisctrl2, sTerrisCtrl2, CLSID_TERRISCTRL2); + + +QUERYINTERFACE_BEGIN(terrisctrl2, CLSID_TERRISCTRL2) +QUERYINTERFACE_ITEM(IID_HDL4SEUNIT, IHDL4SEUnit, sTerrisCtrl2) +QUERYINTERFACE_ITEM(IID_HDL4SEDETECTOR, IHDL4SEDetector, sTerrisCtrl2) +QUERYINTERFACE_ITEM(IID_DLIST, IDList, sTerrisCtrl2) +QUERYINTERFACE_END + +static const char* terrisctrl2ModuleInfo() +{ + return "1.0.0-20210617.1949 Terris Controller V2"; +} + +static int terrisctrl2Create(const PARAMITEM* pParams, int paramcount, HOBJECT* pObject) +{ + sTerrisCtrl2* pobj; + int i; + pobj = (sTerrisCtrl2*)malloc(sizeof(sTerrisCtrl2)); + if (pobj == NULL) + return -1; + *pObject = 0; + HDL4SEUNIT_VARINIT(pobj, CLSID_TERRISCTRL2); + INTERFACE_INIT(IHDL4SEUnit, pobj, terrisctrl2, hdl4se_unit); + INTERFACE_INIT(IHDL4SEDetector, pobj, terrisctrl2, hdl4se_detector); + DLIST_VARINIT(pobj, terrisctrl2); + + pobj->name = NULL; + pobj->parent = NULL; + pobj->readdata_unit = NULL; + pobj->readdata_unit1 = NULL; + pobj->readdata = bigintegerCreate(32); + pobj->lastreaddata = bigintegerCreate(32); + pobj->readdata1 = bigintegerCreate(32); + pobj->lastreaddata1 = bigintegerCreate(32); + pobj->currentline = 0; + 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; + } + } + pobj->write = 1; + pobj->write1 = 0; + terrisInit(); + /* 返回生成的对象 */ + OBJECT_RETURN_GEN(terrisctrl2, pobj, pObject, CLSID_TERRISCTRL2); + return EIID_OK; +} + +static void terrisctrl2Destroy(HOBJECT object) +{ + sTerrisCtrl2* pobj; + int i; + pobj = (sTerrisCtrl2*)objectThis(object); + if (pobj->name != NULL) + free(pobj->name); + memset(pobj, 0, sizeof(sTerrisCtrl2)); + free(pobj); +} + +static int terrisctrl2Valid(HOBJECT object) +{ + sTerrisCtrl2* pobj; + pobj = (sTerrisCtrl2*)objectThis(object); + return 1; +} + +static int terrisctrl2_hdl4se_unit_Connect(HOBJECT object, int index, HOBJECT from, int fromindex) +{ + sTerrisCtrl2* pobj; + IHDL4SEUnit** unit = NULL; + pobj = (sTerrisCtrl2*)objectThis(object); + if (index == 5) { + if (0 == objectQueryInterface(from, IID_HDL4SEUNIT, (void**)&unit)) { + objectRelease(pobj->readdata_unit); + pobj->readdata_unit = unit; + pobj->readdata_index = fromindex; + } + } + else + if (index == 10) { + if (0 == objectQueryInterface(from, IID_HDL4SEUNIT, (void**)&unit)) { + objectRelease(pobj->readdata_unit1); + pobj->readdata_unit1 = unit; + pobj->readdata_index1 = fromindex; + } + } + return 0; +} + +static int terrisctrl2_hdl4se_unit_ConnectPart(HOBJECT object, int index, int start, int width, HOBJECT from, int fromindex) +{ + sTerrisCtrl2* pobj; + IHDL4SEUnit** unit = NULL; + pobj = (sTerrisCtrl2*)objectThis(object); + return 0; +} + +static int terrisctrl2_hdl4se_unit_GetValue(HOBJECT object, int index, int width, IBigNumber ** value) +{ + int i; + sTerrisCtrl2* pobj; + pobj = (sTerrisCtrl2*)objectThis(object); + if (index == 2) { + objectCall1(value, AssignUint32, pobj->write); + } + else if (index == 3) { + objectCall1(value, AssignUint32, pobj->writeaddr); + } + else if (index == 4) { + objectCall1(value, AssignUint32, pobj->writedata); + } + if (index == 6) { + objectCall1(value, AssignUint32, pobj->write1); + } + else if (index == 7) { + objectCall1(value, AssignUint32, pobj->writeaddr1); + } + else if (index == 8) { + objectCall1(value, AssignUint32, pobj->writedata1); + } + else if (index == 9) { + objectCall1(value, AssignUint32, pobj->readaddr1); + } + return 0; +} + +static int terrisctrl2_hdl4se_unit_ClkTick(HOBJECT object) +{ + sTerrisCtrl2* pobj; + + pobj = (sTerrisCtrl2*)objectThis(object); + objectCall3(pobj->readdata_unit, GetValue, pobj->readdata_index, 32, pobj->readdata); + if (!objectCall1(pobj->readdata, IsEQ, pobj->lastreaddata)) { + unsigned int key; + objectCall1(pobj->readdata, GetUint32, &key); + objectCall1(pobj->lastreaddata, AssignU, pobj->readdata); + if (key & 1) + terrisPressKey(TK_RIGHT); + if (key & 2) + terrisPressKey(TK_LEFT); + if (key & 4) + terrisPressKey(TK_DOWN); + if (key & 8) + terrisPressKey(TK_TURNLEFT); + } + terrisTick(); + return 0; +} + +static unsigned int get_line_data(sTerrisCtrl2* pobj, int line, int right) +{ + unsigned int data; + int i; + data = 0; + line = YCOUNT - 1 - line; + for (i = 0; i < 8; i++) { + int xx, yy, ii, jj; + unsigned int c; + xx = 7 - i + right * 8; + yy = line; + c = 0; + jj = xx - currentblock.posx + BLOCKSIZE / 2; + ii = yy - currentblock.posy + BLOCKSIZE / 2; + if (ii >= 0 && ii < BLOCKSIZE && jj >= 0 && jj < BLOCKSIZE) { + c = currentblock.subblock[ii][jj]; + } + + data <<= 4; + if (c == 0) + data |= terrisPanel[line][7 - i + right * 8] & 0xf; + else + data |= c & 0xf; + + } + return data; +} + +static int terrisctrl2_hdl4se_unit_Setup(HOBJECT object) +{ + sTerrisCtrl2* pobj; + pobj = (sTerrisCtrl2*)objectThis(object); + /* 每个周期更新半行 */ + if (pobj->currentline >= 0 && pobj->currentline < YCOUNT * 2) { + pobj->writeaddr = 0x10 + pobj->currentline * 4; + pobj->writedata = get_line_data(pobj, pobj->currentline / 2, pobj->currentline & 1); + } + else if (pobj->currentline == YCOUNT * 2 + 0) { + pobj->writeaddr = 0xe0; + pobj->writedata = + ((nextblock.subblock[0][0] & 0xf) << 0) + | ((nextblock.subblock[0][1] & 0xf) << 4) + | ((nextblock.subblock[0][2] & 0xf) << 8) + | ((nextblock.subblock[0][3] & 0xf) << 12) + | ((nextblock.subblock[1][0] & 0xf) << 16) + | ((nextblock.subblock[1][1] & 0xf) << 20) + | ((nextblock.subblock[1][2] & 0xf) << 24) + | ((nextblock.subblock[1][3] & 0xf) << 28) + ; + } + else if (pobj->currentline == YCOUNT * 2 + 1) { + pobj->writeaddr = 0xe4; + pobj->writedata = + ((nextblock.subblock[2][0] & 0xf) << 0) + | ((nextblock.subblock[2][1] & 0xf) << 4) + | ((nextblock.subblock[2][2] & 0xf) << 8) + | ((nextblock.subblock[2][3] & 0xf) << 12) + | ((nextblock.subblock[3][0] & 0xf) << 16) + | ((nextblock.subblock[3][1] & 0xf) << 20) + | ((nextblock.subblock[3][2] & 0xf) << 24) + | ((nextblock.subblock[3][3] & 0xf) << 28) + ; + } + else if (pobj->currentline == YCOUNT * 2 + 2) { + pobj->writeaddr = 0xf0; + pobj->writedata = gameScore; + } + else if (pobj->currentline == YCOUNT * 2 + 3) { + pobj->writeaddr = 0xf4; + pobj->writedata = gameLevel; + } + else if (pobj->currentline == YCOUNT * 2 + 4) { + pobj->writeaddr = 0xf8; + pobj->writedata = MAXSPPED - currentspeed; + } + pobj->currentline = pobj->currentline + 1; + if (pobj->currentline > YCOUNT * 2 + 4) + pobj->currentline = 0; + return 0; +} + +static int terrisctrl2_hdl4se_detector_GetName(HOBJECT object, const char** pname) +{ + sTerrisCtrl2* pobj; + pobj = (sTerrisCtrl2*)objectThis(object); + *pname = pobj->name; + return 0; +} + +static int terrisctrl2_hdl4se_detector_GetSignalCount(HOBJECT object) +{ + sTerrisCtrl2* pobj; + pobj = (sTerrisCtrl2*)objectThis(object); + return 0; +} + +static int terrisctrl2_hdl4se_detector_GetSignalInfo(HOBJECT object, int index, const char** pname, int * width) +{ + sTerrisCtrl2* pobj; + pobj = (sTerrisCtrl2*)objectThis(object); + return 0; +} + +static int terrisctrl2_hdl4se_detector_GetSignalValue(HOBJECT object, int index, IBigNumber** value) +{ + sTerrisCtrl2* pobj; + pobj = (sTerrisCtrl2*)objectThis(object); + return 0; +} + +static int terrisctrl2_hdl4se_detector_GetUnitCount(HOBJECT object) +{ + sTerrisCtrl2* pobj; + pobj = (sTerrisCtrl2*)objectThis(object); + return 0; +} + +static int terrisctrl2_hdl4se_detector_GetUnit(HOBJECT object, int index, HOBJECT* unit) +{ + sTerrisCtrl2* pobj; + pobj = (sTerrisCtrl2*)objectThis(object); + return 0; +} + diff --git a/examples/terris/src/topmodule.c b/examples/terris/src/topmodule.c index b0db70c436d4f9a8c7f5e9b895ca665c6bc415be..71dedf88011ec6d04e313684b4371ad6d6db6362 100644 --- a/examples/terris/src/topmodule.c +++ b/examples/terris/src/topmodule.c @@ -31,7 +31,7 @@ /* -* Created by HDL4SE @ Thu Jun 17 17:42:07 2021 +* Created by HDL4SE @ Thu Jun 17 20:24:38 2021 * Don't edit it. */ @@ -51,7 +51,7 @@ IHDL4SEUnit** hdl4seCreate_0011(IHDL4SEModule** parent, const char* instancepara { /* module main */ IHDL4SEModule** module; IHDL4SEUnit** unit; - IHDL4SEUnit** nets[8]; + IHDL4SEUnit** nets[14]; IHDL4SEUnit** modules[4]; /* 生成模块对象 */ @@ -71,59 +71,77 @@ IHDL4SEUnit** hdl4seCreate_0011(IHDL4SEModule** parent, const char* instancepara /* 8*/ objectCall3(module, AddPort, 32, PORT_DIRECT_INPUT , "bReadData"); /* 线网 */ - nets[ 0] = hdl4seCreateUnit(module, CLSID_HDL4SE_WIRE, " 6", "bram0_WriteAddr"); - nets[ 1] = hdl4seCreateUnit(module, CLSID_HDL4SE_WIRE, " 32", "bram0_WriteData"); - nets[ 2] = hdl4seCreateUnit(module, CLSID_HDL4SE_WIRE, " 32", "ctrlWriteAddr"); - nets[ 3] = hdl4seCreateUnit(module, CLSID_HDL4SE_WIRE, " 32", "ctrlWriteAddr1"); - nets[ 4] = hdl4seCreateUnit(module, CLSID_HDL4SE_WIRE, " 7", "wirein_readaddr"); - nets[ 5] = hdl4seCreateUnit(module, CLSID_HDL4SE_WIRE, " 7", "wireout_readaddr"); - nets[ 6] = hdl4seCreateUnit(module, CLSID_HDL4SE_WIRE, " 7", "wireout_readaddr1"); - nets[ 7] = hdl4seCreateUnit(module, CLSID_HDL4SE_WIRE, " 32", "wireout_readaddr2"); + nets[ 0] = hdl4seCreateUnit(module, CLSID_HDL4SE_WIRE, " 1", "wram0_Write"); + nets[ 1] = hdl4seCreateUnit(module, CLSID_HDL4SE_WIRE, " 6", "bram0_WriteAddr"); + nets[ 2] = hdl4seCreateUnit(module, CLSID_HDL4SE_WIRE, " 32", "bram0_WriteData"); + nets[ 3] = hdl4seCreateUnit(module, CLSID_HDL4SE_WIRE, " 1", "wram_Write1"); + nets[ 4] = hdl4seCreateUnit(module, CLSID_HDL4SE_WIRE, " 6", "bram_WriteAddr1"); + nets[ 5] = hdl4seCreateUnit(module, CLSID_HDL4SE_WIRE, " 32", "bram_WriteData1"); + nets[ 6] = hdl4seCreateUnit(module, CLSID_HDL4SE_WIRE, " 6", "bram_ReadAddr1"); + nets[ 7] = hdl4seCreateUnit(module, CLSID_HDL4SE_WIRE, " 32", "bram_ReadData1"); + nets[ 8] = hdl4seCreateUnit(module, CLSID_HDL4SE_WIRE, " 32", "ctrlWriteAddr"); + nets[ 9] = hdl4seCreateUnit(module, CLSID_HDL4SE_WIRE, " 32", "ctrlWriteAddr1"); + nets[ 10] = hdl4seCreateUnit(module, CLSID_HDL4SE_WIRE, " 7", "wirein_readaddr"); + nets[ 11] = hdl4seCreateUnit(module, CLSID_HDL4SE_WIRE, " 7", "wireout_readaddr"); + nets[ 12] = hdl4seCreateUnit(module, CLSID_HDL4SE_WIRE, " 7", "wireout_readaddr1"); + nets[ 13] = hdl4seCreateUnit(module, CLSID_HDL4SE_WIRE, " 32", "wireout_readaddr2"); /* 模块实例化 */ - modules[ 0] = hdl4seCreateUnit2(module, "6f8a9aa6-ec57-4734-a183-7871ed57ea95", "", "ctrl"); + modules[ 0] = hdl4seCreateUnit2(module, "9d063daf-a778-4652-a6cb-a8a6ec569044", "", "ctrl"); objectCall3(modules[0], Connect, 0, unit, 0); objectCall3(modules[0], Connect, 1, unit, 1); - objectCall3(nets[2], Connect, 0, modules[0], 2); - objectCall3(nets[1], Connect, 0, modules[0], 3); - objectCall3(modules[0], Connect, 4, unit, 8); - modules[ 1] = hdl4seCreateUnit2(module, "dffb1080-8b92-4b42-a607-d1b377c27bb1", "32, 6", "ram_0"); + objectCall3(nets[0], Connect, 0, modules[0], 2); + objectCall3(nets[8], Connect, 0, modules[0], 3); + objectCall3(nets[2], Connect, 0, modules[0], 4); + objectCall3(modules[0], Connect, 5, unit, 8); + objectCall3(nets[3], Connect, 0, modules[0], 6); + objectCall3(nets[4], Connect, 0, modules[0], 7); + objectCall3(nets[5], Connect, 0, modules[0], 8); + objectCall3(nets[6], Connect, 0, modules[0], 9); + objectCall3(modules[0], Connect, 10, nets[7], 0); + modules[ 1] = hdl4seCreateUnit2(module, "d26dddb3-0fdf-48c6-b4f3-4042eff8ca79", "32, 6", "ram_0"); objectCall3(modules[1], Connect, 0, unit, 0); objectCall3(modules[1], Connect, 1, nets[0], 0); objectCall3(modules[1], Connect, 2, nets[1], 0); - objectCall3(modules[1], Connect, 3, nets[5], 0); - objectCall3(unit, Connect, 4, modules[1], 4); + objectCall3(modules[1], Connect, 3, nets[2], 0); + objectCall3(modules[1], Connect, 4, nets[11], 0); + objectCall3(unit, Connect, 4, modules[1], 5); + objectCall3(modules[1], Connect, 6, nets[3], 0); + objectCall3(modules[1], Connect, 7, nets[4], 0); + objectCall3(modules[1], Connect, 8, nets[5], 0); + objectCall3(modules[1], Connect, 9, nets[6], 0); + objectCall3(nets[7], Connect, 0, modules[1], 10); modules[ 2] = hdl4seCreateUnit2(module, "76FBFD4B-FEAD-45fd-AA27-AFC58AC241C2", "6", "readaddr"); objectCall3(modules[2], Connect, 0, unit, 0); - objectCall3(modules[2], Connect, 1, nets[4], 0); - objectCall3(nets[5], Connect, 0, modules[2], 2); + objectCall3(modules[2], Connect, 1, nets[10], 0); + objectCall3(nets[11], Connect, 0, modules[2], 2); modules[ 3] = hdl4seCreateUnit2(module, "76FBFD4B-FEAD-45fd-AA27-AFC58AC241C2", "6", "readaddr1"); objectCall3(modules[3], Connect, 0, unit, 0); - objectCall3(modules[3], Connect, 1, nets[5], 0); - objectCall3(nets[6], Connect, 0, modules[3], 2); + objectCall3(modules[3], Connect, 1, nets[11], 0); + objectCall3(nets[12], Connect, 0, modules[3], 2); /* 持续性赋值 */ /* assign ctrlWriteAddr1 = ctrlWriteAddr-32'h10; */ IHDL4SEUnit** tempvar_1 = hdl4seCreateUnit(module, CLSID_HDL4SE_CONST, "32, 32'h10", "tempvar_1"); IHDL4SEUnit **tempvar_0 = hdl4seCreateUnit(module, CLSID_HDL4SE_BINOP, "32, 32, 32, 1", "tempvar_0"); - objectCall3(tempvar_0, Connect, 0, nets[2], 0); + objectCall3(tempvar_0, Connect, 0, nets[8], 0); objectCall3(tempvar_0, Connect, 1, tempvar_1, 0); - objectCall3(nets[3], Connect, 0, tempvar_0, 2); + objectCall3(nets[9], Connect, 0, tempvar_0, 2); /* assign bram0_WriteAddr = ctrlWriteAddr1 [7:2] ; */ IHDL4SEUnit** tempvar_2 = hdl4seCreateUnit(module, CLSID_HDL4SE_SPLIT1, "32, 6, 2", "tempvar_2"); - objectCall3(tempvar_2, Connect, 0, nets[3], 0); - objectCall3(nets[0], Connect, 0, tempvar_2, 1); + objectCall3(tempvar_2, Connect, 0, nets[9], 0); + objectCall3(nets[1], Connect, 0, tempvar_2, 1); /* assign wirein_readaddr = wireout_readaddr+1; */ IHDL4SEUnit** tempvar_4 = hdl4seCreateUnit(module, CLSID_HDL4SE_CONST, "2, 1", "tempvar_4"); IHDL4SEUnit **tempvar_3 = hdl4seCreateUnit(module, CLSID_HDL4SE_BINOP, "32, 32, 32, 0", "tempvar_3"); - objectCall3(tempvar_3, Connect, 0, nets[5], 0); + objectCall3(tempvar_3, Connect, 0, nets[11], 0); objectCall3(tempvar_3, Connect, 1, tempvar_4, 0); - objectCall3(nets[4], Connect, 0, tempvar_3, 2); + objectCall3(nets[10], Connect, 0, tempvar_3, 2); /* assign bWriteAddr = 32'hf0000010+wireout_readaddr1*4; */ IHDL4SEUnit** tempvar_6 = hdl4seCreateUnit(module, CLSID_HDL4SE_CONST, "32, 32'hf0000010", "tempvar_6"); IHDL4SEUnit** tempvar_8 = hdl4seCreateUnit(module, CLSID_HDL4SE_CONST, "4, 4", "tempvar_8"); IHDL4SEUnit **tempvar_7 = hdl4seCreateUnit(module, CLSID_HDL4SE_BINOP, "32, 32, 32, 2", "tempvar_7"); - objectCall3(tempvar_7, Connect, 0, nets[6], 0); + objectCall3(tempvar_7, Connect, 0, nets[12], 0); objectCall3(tempvar_7, Connect, 1, tempvar_8, 0); IHDL4SEUnit **tempvar_5 = hdl4seCreateUnit(module, CLSID_HDL4SE_BINOP, "32, 32, 32, 0", "tempvar_5"); objectCall3(tempvar_5, Connect, 0, tempvar_6, 0); diff --git a/examples/terris/verilog/main.v b/examples/terris/verilog/main.v index f57e10ebec5c8a0797ae37c0b70bb5305af4b33b..e28a2df8ea983373708a08c7f2f4e38d8c87b69d 100644 --- a/examples/terris/verilog/main.v +++ b/examples/terris/verilog/main.v @@ -43,6 +43,7 @@ module teris_ctrl ( input wClk, input nwReset, + output wWrite, output [31:0] bWriteAddr, output [31:0] bWriteData, input [31:0] bKeyPressed @@ -59,14 +60,13 @@ module main( output [31:0] bReadAddr, input [31:0] bReadData); + wire [31:0] bctrlwaddr; + assign bWriteAddr = bctrlwaddr + 32'hf000_0000; /* 游戏控制器 */ - teris_ctrl ctrl(wClk, nwReset, bWriteAddr, bWriteData, bReadData); + teris_ctrl ctrl(wClk, nwReset,wWrite, bctrlwaddr, bWriteData, bReadData); /*我们一直在读按键的状态*/ assign wRead = 1'b1; assign bReadAddr = 32'hF000_0000; -/*总在写*/ - assign wWrite = 1'b1; - endmodule diff --git a/examples/terris/verilog/main_1.v b/examples/terris/verilog/main_1.v index 14d2c8b03903ec4d8855ba0d88e08a48a8572275..647b7ec67adb0928a7d9f0b0d10a1fb00258a660 100644 --- a/examples/terris/verilog/main_1.v +++ b/examples/terris/verilog/main_1.v @@ -43,6 +43,7 @@ module teris_ctrl ( input wClk, input nwReset, + output wWrite, output [31:0] bWriteAddr, output [31:0] bWriteData, input [31:0] bKeyPressed @@ -59,24 +60,27 @@ module main( output [31:0] bReadAddr, input [31:0] bReadData); + wire wram0_Write; wire [5:0] bram0_WriteAddr; wire [31:0] bram0_WriteData; /* 游戏控制器 */ wire [31:0] ctrlWriteAddr, ctrlWriteAddr1; - teris_ctrl ctrl(wClk, nwReset, ctrlWriteAddr, bram0_WriteData, bReadData); + teris_ctrl ctrl(wClk, nwReset, wram0_Write, ctrlWriteAddr, bram0_WriteData, bReadData); assign ctrlWriteAddr1 = ctrlWriteAddr - 32'h10; assign bram0_WriteAddr = ctrlWriteAddr1[7:2] ; //hdl4se_split1 #(32, 6, 2) ctrl2ram_addr(ctrlWriteAddr1, bram0_WriteAddr); + /* 帧存存储器 */ hdl4se_ram1p #(32, 6) ram_0( wClk, + wram0_Write, bram0_WriteAddr, bram0_WriteData, wireout_readaddr, - bWriteData + bWriteData, ); /* 将帧存读出来写到游戏面板的状态,不断从帧存中取数据,写到面板中去 */ wire [6:0] wirein_readaddr, wireout_readaddr, wireout_readaddr1; @@ -96,5 +100,4 @@ module main( assign wRead = 1'b1; assign bReadAddr = 32'hF000_0000; - endmodule diff --git a/examples/terris/verilog/main_2.v b/examples/terris/verilog/main_2.v new file mode 100644 index 0000000000000000000000000000000000000000..5d47f4fa5fb6fe5894d7d5a1dc112f92acdf651e --- /dev/null +++ b/examples/terris/verilog/main_2.v @@ -0,0 +1,119 @@ + +/* +** 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. +*/ +/* main.v */ + +`include "hdl4secell.v" + +/* 用c写的俄罗斯方块控制器 */ +(* + HDL4SE="LCOM", + CLSID="9d063daf-a778-4652-a6cb-a8a6ec569044", + softmodule="hdl4se" +*) +module teris_ctrl2 + ( + input wClk, + input nwReset, + output wWrite, + output [31:0] bWriteAddr, + output [31:0] bWriteData, + input [31:0] bKeyPressed, + output wWrite1, + output [31:0] bWriteAddr1, + output [31:0] bWriteData1, + output [31:0] bReadAddr1, + input [31:0] bReadData1 + ); +endmodule + +module main( + input wClk, nwReset, + output wWrite, + output [31:0] bWriteAddr, + output [31:0] bWriteData, + output [3:0] bWriteMask, + output wRead, + output [31:0] bReadAddr, + input [31:0] bReadData); + + wire wram0_Write; + wire [5:0] bram0_WriteAddr; + wire [31:0] bram0_WriteData; + + wire wram_Write1; + wire [5:0] bram_WriteAddr1; + wire [31:0] bram_WriteData1; + wire [5:0] bram_ReadAddr1; + wire [31:0] bram_ReadData1; + +/* 游戏控制器 */ + wire [31:0] ctrlWriteAddr, ctrlWriteAddr1; + teris_ctrl2 ctrl(wClk, nwReset, wram0_Write, ctrlWriteAddr, bram0_WriteData, bReadData, + wram_Write1, bram_WriteAddr1, bram_WriteData1, bram_ReadAddr1, bram_ReadData1 + ); + + assign ctrlWriteAddr1 = ctrlWriteAddr - 32'h10; + assign bram0_WriteAddr = ctrlWriteAddr1[7:2] ; + +/* 帧存存储器 */ + hdl4se_ram2p #(32, 6) ram_0( + wClk, + wram0_Write, + bram0_WriteAddr, + bram0_WriteData, + wireout_readaddr, + bWriteData, + wram_Write1, + bram_WriteAddr1, + bram_WriteData1, + bram_ReadAddr1, + bram_ReadData1 + ); +/* 将帧存读出来写到游戏面板的状态,不断从帧存中取数据,写到面板中去 */ + wire [6:0] wirein_readaddr, wireout_readaddr, wireout_readaddr1; + wire[31:0] wireout_readaddr2; + hdl4se_reg #(6) readaddr(wClk, wirein_readaddr, wireout_readaddr); + hdl4se_reg #(6) readaddr1(wClk, wireout_readaddr, wireout_readaddr1); + /*地址每个周期增加1*/ + assign wirein_readaddr = wireout_readaddr + 1; + /* 生成设备写地址 */ + assign bWriteAddr = 32'hf000_0010 + wireout_readaddr1 * 4; + +/*总在写*/ + assign wWrite = 1'b1; + assign bWriteMask = 4'b0; + +/*我们一直在读按键的状态*/ + assign wRead = 1'b1; + assign bReadAddr = 32'hF000_0000; + +endmodule diff --git a/examples/terris/verilog/main_asm.v b/examples/terris/verilog/main_asm.v index 6bd0c411c6367435d7108fabc656c7c510e0008f..4bf29b3213d705d34ca33597b4163959e30a1c1d 100644 --- a/examples/terris/verilog/main_asm.v +++ b/examples/terris/verilog/main_asm.v @@ -303,6 +303,7 @@ module hdl4se_ram1p ) ( input wClk, + input wWrite, input [ADDRWIDTH-1:0] bWriteAddr, input [WIDTH-1:0] bWriteData, input [ADDRWIDTH-1:0] bReadAddr, @@ -324,10 +325,12 @@ module hdl4se_ram2p ) ( input wClk, + input wWrite1, input [ADDRWIDTH-1:0] bWriteAddr1, input [WIDTH-1:0] bWriteData1, input [ADDRWIDTH-1:0] bReadAddr1, output [WIDTH-1:0] bReadData1, + input wWrite2, input [ADDRWIDTH-1:0] bWriteAddr2, input [WIDTH-1:0] bWriteData2, input [ADDRWIDTH-1:0] bReadAddr2, @@ -422,16 +425,22 @@ endmodule (* HDL4SE = "LCOM", - CLSID = "6f8a9aa6-ec57-4734-a183-7871ed57ea95", + CLSID = "9d063daf-a778-4652-a6cb-a8a6ec569044", softmodule = "hdl4se" *) -module teris_ctrl +module teris_ctrl2 ( input wClk, input nwReset, + output wWrite, output [31:0] bWriteAddr, output [31:0] bWriteData, - input [31:0] bKeyPressed + input [31:0] bKeyPressed, + output wWrite1, + output [31:0] bWriteAddr1, + output [31:0] bWriteData1, + output [31:0] bReadAddr1, + input [31:0] bReadData1 ) ; endmodule @@ -450,8 +459,14 @@ module main input [31:0] bReadData ) ; + wire wram0_Write; wire [5:0] bram0_WriteAddr; wire [31:0] bram0_WriteData; + wire wram_Write1; + wire [5:0] bram_WriteAddr1; + wire [31:0] bram_WriteData1; + wire [5:0] bram_ReadAddr1; + wire [31:0] bram_ReadData1; wire [31:0] ctrlWriteAddr; wire [31:0] ctrlWriteAddr1; wire [6:0] wirein_readaddr; @@ -466,8 +481,12 @@ module main assign bWriteMask = 32'h0; assign wRead = 32'h1; assign bReadAddr = 32'hf0000000; - teris_ctrl ctrl( wClk, nwReset, ctrlWriteAddr, bram0_WriteData, bReadData ); - hdl4se_ram1p #( 32, 6 ) ram_0( wClk, bram0_WriteAddr, bram0_WriteData, wireout_readaddr, bWriteData ); + teris_ctrl2 ctrl( wClk, nwReset, wram0_Write, ctrlWriteAddr, bram0_WriteData, bReadData + , wram_Write1, bram_WriteAddr1, bram_WriteData1, bram_ReadAddr1, bram_ReadData1 + ); + hdl4se_ram2p #( 32, 6 ) ram_0( wClk, wram0_Write, bram0_WriteAddr, bram0_WriteData, wireout_readaddr, bWriteData + , wram_Write1, bram_WriteAddr1, bram_WriteData1, bram_ReadAddr1, bram_ReadData1 + ); hdl4se_reg #( 6 ) readaddr( wClk, wirein_readaddr, wireout_readaddr ); hdl4se_reg #( 6 ) readaddr1( wClk, wireout_readaddr, wireout_readaddr1 ); endmodule diff --git a/hdl4secell/src/hdl4se_ram1p.c b/hdl4secell/src/hdl4se_ram1p.c index 3120c11ca48dda2938d93bbd1a151a60b249bc86..b7bffa451e149f298e7005a61d70ddc695406043 100644 --- a/hdl4secell/src/hdl4se_ram1p.c +++ b/hdl4secell/src/hdl4se_ram1p.c @@ -49,7 +49,7 @@ instance parameter: "8, 4", width=8, addrwidth=4 */ #define RWPORTCOUNT 1 -#define INPUTCOUNT 3 +#define INPUTCOUNT 4 typedef struct _sHDL4SERam1P { OBJECT_HEADER @@ -166,9 +166,10 @@ static int hdl4se_ram1pCreate(const PARAMITEM* pParams, int paramcount, HOBJECT* return EIID_INVALIDPARAM; for (i = 0; i < RWPORTCOUNT; i++) { - pobj->in_data[i * INPUTCOUNT + 0] = bigintegerCreate(pobj->addrwidth); /*bWriteAddr*/ - pobj->in_data[i * INPUTCOUNT + 1] = bigintegerCreate(pobj->width); /*bWriteData*/ - pobj->in_data[i * INPUTCOUNT + 2] = bigintegerCreate(pobj->addrwidth); /*bReadAddr*/ + pobj->in_data[i * INPUTCOUNT + 0] = bigintegerCreate(1); /*wWrite*/ + pobj->in_data[i * INPUTCOUNT + 1] = bigintegerCreate(pobj->addrwidth); /*bWriteAddr*/ + pobj->in_data[i * INPUTCOUNT + 2] = bigintegerCreate(pobj->width); /*bWriteData*/ + pobj->in_data[i * INPUTCOUNT + 3] = bigintegerCreate(pobj->addrwidth); /*bReadAddr*/ pobj->out_data[i] = bigintegerCreate(pobj->width); /*bReadData*/ } @@ -271,19 +272,24 @@ static int hdl4se_ram1p_hdl4se_unit_ClkTick(HOBJECT object) pobj = (sHDL4SERam1P*)objectThis(object); for (i = 0; i < RWPORTCOUNT; i++) { unsigned int addr; - objectCall3(pobj->in[i * INPUTCOUNT + 0], GetValue, pobj->in_index[i * INPUTCOUNT + 0], pobj->addrwidth, pobj->in_data[i * INPUTCOUNT + 0]); /*bWriteAddr*/ - objectCall3(pobj->in[i * INPUTCOUNT + 1], GetValue, pobj->in_index[i * INPUTCOUNT + 1], pobj->width, pobj->in_data[i * INPUTCOUNT + 1]); /*bWriteData*/ - objectCall3(pobj->in[i * INPUTCOUNT + 2], GetValue, pobj->in_index[i * INPUTCOUNT + 2], pobj->addrwidth, pobj->in_data[i * INPUTCOUNT + 2]); /*bReadAddr*/ + unsigned int write; + objectCall3(pobj->in[i * INPUTCOUNT + 0], GetValue, pobj->in_index[i * INPUTCOUNT + 0], pobj->addrwidth, pobj->in_data[i * INPUTCOUNT + 0]); /*wWrite*/ + objectCall3(pobj->in[i * INPUTCOUNT + 1], GetValue, pobj->in_index[i * INPUTCOUNT + 1], pobj->addrwidth, pobj->in_data[i * INPUTCOUNT + 1]); /*bWriteAddr*/ + objectCall3(pobj->in[i * INPUTCOUNT + 2], GetValue, pobj->in_index[i * INPUTCOUNT + 2], pobj->width, pobj->in_data[i * INPUTCOUNT + 2]); /*bWriteData*/ + objectCall3(pobj->in[i * INPUTCOUNT + 3], GetValue, pobj->in_index[i * INPUTCOUNT + 3], pobj->addrwidth, pobj->in_data[i * INPUTCOUNT + 3]); /*bReadAddr*/ /* write data to buf */ /*每个字在32位对齐*/ - objectCall1(pobj->in_data[i * INPUTCOUNT + 0], GetUint32, &addr); - if (addr < pobj->wordcount) { - int j; - for (j = 0; j < pobj->wordsize; j++) { - unsigned int writedata; - unsigned int bufdata; - objectCall2(pobj->in_data[i * INPUTCOUNT + 1], GetBits32, j, &writedata); - pobj->data[addr * pobj->wordsize + j] = writedata; + objectCall1(pobj->in_data[i * INPUTCOUNT + 0], GetUint32, &write); + if (write) { + objectCall1(pobj->in_data[i * INPUTCOUNT + 1], GetUint32, &addr); + if (addr < pobj->wordcount) { + int j; + for (j = 0; j < pobj->wordsize; j++) { + unsigned int writedata; + unsigned int bufdata; + objectCall2(pobj->in_data[i * INPUTCOUNT + 2], GetBits32, j, &writedata); + pobj->data[addr * pobj->wordsize + j] = writedata; + } } } @@ -299,7 +305,7 @@ static int hdl4se_ram1p_hdl4se_unit_Setup(HOBJECT object) for (i = 0; i < RWPORTCOUNT; i++) { /*Read data to out_data*/ unsigned int addr; - objectCall1(pobj->in_data[i * INPUTCOUNT + 2], GetUint32, &addr); + objectCall1(pobj->in_data[i * INPUTCOUNT + 3], GetUint32, &addr); if (addr < pobj->wordcount) { int j; for (j = 0; j < pobj->wordsize; j++) { @@ -329,6 +335,7 @@ static int hdl4se_ram1p_hdl4se_detector_GetSignalCount(HOBJECT object) static const char* portname[RWPORTCOUNT * (INPUTCOUNT+1) + 1] = { "wClk", + "wWrite" "bWriteAddr", "bWriteData", "bReadAddr", @@ -347,7 +354,10 @@ static int hdl4se_ram1p_hdl4se_detector_GetSignalInfo(HOBJECT object, int index, *width = 1; index--; index %= (INPUTCOUNT+1); - if (index == 0 || index == 3) + if (index == 0) + *width = 1; + else + if (index == 1 || index == 4) *width = pobj->addrwidth; else *width = pobj->width; diff --git a/hdl4secell/src/hdl4se_ram2p.c b/hdl4secell/src/hdl4se_ram2p.c index c082b9b7effd7c4c21a005651e64f78c96e367d3..1d343b8f288a5680e8fe8f281acab3c73e3ea5c3 100644 --- a/hdl4secell/src/hdl4se_ram2p.c +++ b/hdl4secell/src/hdl4se_ram2p.c @@ -43,12 +43,13 @@ #include "bignumber.h" #include "hdl4secell.h" -/* +/* HDL4SE_RAM2P instance parameter: "8, 4", width=8, addrwidth=4 */ #define RWPORTCOUNT 2 +#define INPUTCOUNT 4 typedef struct _sHDL4SERam2P { OBJECT_HEADER @@ -57,17 +58,19 @@ typedef struct _sHDL4SERam2P { INTERFACE_DECLARE(IHDL4SEDetector) HDL4SEDETECTOR_VARDECLARE DLIST_VARDECLARE - + IHDL4SEModule** parent; char* name; int width; int addrwidth; + int wordcount; + int wordsize; - IHDL4SEUnit** in[RWPORTCOUNT * 4]; - int in_index[RWPORTCOUNT * 4]; + IHDL4SEUnit** in[RWPORTCOUNT * INPUTCOUNT]; + int in_index[RWPORTCOUNT * INPUTCOUNT]; - IBigNumber** in_data[RWPORTCOUNT * 4]; + IBigNumber** in_data[RWPORTCOUNT * INPUTCOUNT]; IBigNumber** out_data[RWPORTCOUNT * 1]; unsigned int* data; @@ -90,7 +93,7 @@ QUERYINTERFACE_END static const char* hdl4se_ram2pModuleInfo() { - return "1.0.0-20210610.1610 HDL4SE 2 Port RAM cell"; + return "1.0.0-20210617.1927 HDL4SE 2 Port RAM cell"; } static int wordsofram(int addrwidth) @@ -116,7 +119,7 @@ static int hdl4se_ram2pCreate(const PARAMITEM* pParams, int paramcount, HOBJECT* INTERFACE_INIT(IHDL4SEDetector, pobj, hdl4se_ram2p, hdl4se_detector); DLIST_VARINIT(pobj, hdl4se_ram2p); - for (i = 0; i < RWPORTCOUNT * 4; i++) { + for (i = 0; i < RWPORTCOUNT * INPUTCOUNT; i++) { pobj->in[i] = NULL; pobj->in_index[i] = 0; pobj->in_data[i] = NULL; @@ -125,19 +128,19 @@ static int hdl4se_ram2pCreate(const PARAMITEM* pParams, int paramcount, HOBJECT* pobj->out_data[i] = NULL; } - pobj->name = NULL; - pobj->parent = NULL; pobj->width = 64; pobj->addrwidth = 5; + pobj->name = NULL; + 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; + pobj->parent = (IHDL4SEModule**)pParams[i].pvalue; } else if (pParams[i].name == PARAMID_HDL4SE_UNIT_INSTANCE_PARAMETERS) { IBigNumber** temp = bigintegerCreate(32); @@ -161,16 +164,18 @@ static int hdl4se_ram2pCreate(const PARAMITEM* pParams, int paramcount, HOBJECT* return EIID_INVALIDPARAM; if (pobj->addrwidth <= 0 || pobj->addrwidth > 30) return EIID_INVALIDPARAM; - + for (i = 0; i < RWPORTCOUNT; i++) { - pobj->in_data[i * 4 + 0] = bigintegerCreate(pobj->addrwidth); /*bWriteAddr*/ - pobj->in_data[i * 4 + 1] = bigintegerCreate(pobj->width); /*bWriteData*/ - pobj->in_data[i * 4 + 2] = bigintegerCreate(pobj->width); /*bWriteMask*/ - pobj->in_data[i * 4 + 3] = bigintegerCreate(pobj->addrwidth); /*bReadAddr*/ - pobj->out_data[i] = bigintegerCreate(pobj->width); /*bReadData*/ + pobj->in_data[i * INPUTCOUNT + 0] = bigintegerCreate(1); /*wWrite*/ + pobj->in_data[i * INPUTCOUNT + 1] = bigintegerCreate(pobj->addrwidth); /*bWriteAddr*/ + pobj->in_data[i * INPUTCOUNT + 2] = bigintegerCreate(pobj->width); /*bWriteData*/ + pobj->in_data[i * INPUTCOUNT + 3] = bigintegerCreate(pobj->addrwidth); /*bReadAddr*/ + pobj->out_data[i] = bigintegerCreate(pobj->width); /*bReadData*/ } - pobj->data = (unsigned int *)malloc(((pobj->width + 31) / 32) * wordsofram(pobj->addrwidth)); + pobj->wordcount = wordsofram(pobj->addrwidth); + pobj->wordsize = (pobj->width + 31) / 32; + pobj->data = (unsigned int*)malloc(pobj->wordsize * pobj->wordcount * sizeof(unsigned int)); if (pobj->data == NULL) return -1; @@ -186,13 +191,13 @@ static void hdl4se_ram2pDestroy(HOBJECT object) pobj = (sHDL4SERam2P*)objectThis(object); if (pobj->name != NULL) free(pobj->name); - for (i = 0; i < RWPORTCOUNT * 4; i++) { + for (i = 0; i < RWPORTCOUNT * INPUTCOUNT; i++) { objectRelease(pobj->in[i]); objectRelease(pobj->in_data[i]); } - for (i = 0;i< RWPORTCOUNT;i++) + for (i = 0; i < RWPORTCOUNT; i++) objectRelease(pobj->out_data[i]); - + if (pobj->data) free(pobj->data); memset(pobj, 0, sizeof(sHDL4SERam2P)); @@ -206,7 +211,7 @@ static int hdl4se_ram2pValid(HOBJECT object) return 1; } -static int hdl4se_ram2p_hdl4se_unit_Connect(HOBJECT object, int index, HOBJECT from, int fromindex) +static int hdl4se_ram2p_hdl4se_unit_Connect(HOBJECT object, int index, HOBJECT from, int fromindex) { sHDL4SERam2P* pobj; IHDL4SEUnit** unit = NULL; @@ -215,17 +220,17 @@ static int hdl4se_ram2p_hdl4se_unit_Connect(HOBJECT object, int index, HOBJECT f if (index < 1) return -1; index--; - ind = index % RWPORTCOUNT; - pn = index / 5; - if (ind > 3) + ind = index % (INPUTCOUNT + 1); + pn = index / (INPUTCOUNT + 1); + if (ind >= INPUTCOUNT) return -1; if (pn >= RWPORTCOUNT) return -2; pobj = (sHDL4SERam2P*)objectThis(object); if (0 == objectQueryInterface(from, IID_HDL4SEUNIT, (void**)&unit)) { - objectRelease(pobj->in[index + pn * 4]); - pobj->in[index + pn * 4] = unit; - pobj->in_index[index + pn * 4] = fromindex; + objectRelease(pobj->in[ind + pn * INPUTCOUNT]); + pobj->in[ind + pn * INPUTCOUNT] = unit; + pobj->in_index[ind + pn * INPUTCOUNT] = fromindex; } else { return -1; @@ -241,7 +246,7 @@ static int hdl4se_ram2p_hdl4se_unit_ConnectPart(HOBJECT object, int index, int s return 0; } -static int hdl4se_ram2p_hdl4se_unit_GetValue(HOBJECT object, int index, int width, IBigNumber ** value) +static int hdl4se_ram2p_hdl4se_unit_GetValue(HOBJECT object, int index, int width, IBigNumber** value) { sHDL4SERam2P* pobj; int pn; @@ -249,10 +254,10 @@ static int hdl4se_ram2p_hdl4se_unit_GetValue(HOBJECT object, int index, int widt if (index < 1) return -1; index--; - ind = index % RWPORTCOUNT; - if (ind != 4) + ind = index % (INPUTCOUNT + 1); + if (ind != INPUTCOUNT) return -1; - pn = index / 5; + pn = index / (INPUTCOUNT + 1); if (pn >= RWPORTCOUNT) return -2; pobj = (sHDL4SERam2P*)objectThis(object); @@ -266,11 +271,26 @@ static int hdl4se_ram2p_hdl4se_unit_ClkTick(HOBJECT object) sHDL4SERam2P* pobj; pobj = (sHDL4SERam2P*)objectThis(object); for (i = 0; i < RWPORTCOUNT; i++) { - objectCall3(pobj->in[i * 4 + 0], GetValue, pobj->in_index[i * 4 + 0], pobj->addrwidth, pobj->in_data[i * 4 + 0]); /*bWriteAddr*/ - objectCall3(pobj->in[i * 4 + 1], GetValue, pobj->in_index[i * 4 + 1], pobj->width, pobj->in_data[i * 4 + 1]); /*bWriteData*/ - objectCall3(pobj->in[i * 4 + 2], GetValue, pobj->in_index[i * 4 + 2], pobj->width, pobj->in_data[i * 4 + 2]); /*bWriteMask*/ - objectCall3(pobj->in[i * 4 + 3], GetValue, pobj->in_index[i * 4 + 3], pobj->addrwidth, pobj->in_data[i * 4 + 3]); /*bReadAddr*/ + unsigned int addr, write; + objectCall3(pobj->in[i * INPUTCOUNT + 0], GetValue, pobj->in_index[i * INPUTCOUNT + 0], pobj->addrwidth, pobj->in_data[i * INPUTCOUNT + 0]); /*wWrite*/ + objectCall3(pobj->in[i * INPUTCOUNT + 1], GetValue, pobj->in_index[i * INPUTCOUNT + 1], pobj->addrwidth, pobj->in_data[i * INPUTCOUNT + 1]); /*bWriteAddr*/ + objectCall3(pobj->in[i * INPUTCOUNT + 2], GetValue, pobj->in_index[i * INPUTCOUNT + 2], pobj->width, pobj->in_data[i * INPUTCOUNT + 2]); /*bWriteData*/ + objectCall3(pobj->in[i * INPUTCOUNT + 3], GetValue, pobj->in_index[i * INPUTCOUNT + 3], pobj->addrwidth, pobj->in_data[i * INPUTCOUNT + 3]); /*bReadAddr*/ /* write data to buf */ + /*每个字在32位对齐*/ + objectCall1(pobj->in_data[i * INPUTCOUNT + 0], GetUint32, &write); + if (write) { + objectCall1(pobj->in_data[i * INPUTCOUNT + 1], GetUint32, &addr); + if (addr < pobj->wordcount) { + int j; + for (j = 0; j < pobj->wordsize; j++) { + unsigned int writedata; + unsigned int bufdata; + objectCall2(pobj->in_data[i * INPUTCOUNT + 2], GetBits32, j, &writedata); + pobj->data[addr * pobj->wordsize + j] = writedata; + } + } + } } return 0; @@ -283,7 +303,16 @@ static int hdl4se_ram2p_hdl4se_unit_Setup(HOBJECT object) pobj = (sHDL4SERam2P*)objectThis(object); for (i = 0; i < RWPORTCOUNT; i++) { /*Read data to out_data*/ - + unsigned int addr; + objectCall1(pobj->in_data[i * INPUTCOUNT + 3], GetUint32, &addr); + if (addr < pobj->wordcount) { + int j; + for (j = 0; j < pobj->wordsize; j++) { + unsigned int bufdata; + bufdata = pobj->data[addr * pobj->wordsize + j]; + objectCall2(pobj->out_data[i], SetBits32, j, bufdata); + } + } } return 0; } @@ -300,36 +329,39 @@ static int hdl4se_ram2p_hdl4se_detector_GetSignalCount(HOBJECT object) { sHDL4SERam2P* pobj; pobj = (sHDL4SERam2P*)objectThis(object); - return RWPORTCOUNT * 5 + 1; + return RWPORTCOUNT * (INPUTCOUNT + 1) + 1; } -static const char* portname[RWPORTCOUNT * 5 + 1] = { +static const char* portname[RWPORTCOUNT * (INPUTCOUNT + 1) + 1] = { "wClk", + "wWrite1", "bWriteAddr1", "bWriteData1", - "bWriteMask1", "bReadAddr1", - "bReadData1", + "bReadData1" + "wWrite2", "bWriteAddr2", "bWriteData2", - "bWriteMask2", "bReadAddr2", "bReadData2" }; -static int hdl4se_ram2p_hdl4se_detector_GetSignalInfo(HOBJECT object, int index, const char** pname, int * width) +static int hdl4se_ram2p_hdl4se_detector_GetSignalInfo(HOBJECT object, int index, const char** pname, int* width) { sHDL4SERam2P* pobj; pobj = (sHDL4SERam2P*)objectThis(object); if (index < 0) return -1; - if (index >= 0 && index < RWPORTCOUNT * 5 + 1) + if (index >= 0 && index < RWPORTCOUNT * (INPUTCOUNT + 1) + 1) *pname = portname[index]; if (index == 0) *width = 1; index--; - index %= 5; - if (index == 0 || index == 3) + index %= (INPUTCOUNT + 1); + if (index == 0) + *width = 1; + else + if (index == 1 || index == 4) *width = pobj->addrwidth; else *width = pobj->width; @@ -344,13 +376,13 @@ static int hdl4se_ram2p_hdl4se_detector_GetSignalValue(HOBJECT object, int index if (index <= 0) return -1; index--; - pn = index / 5; - index %= 5; - if (index == 4) { + pn = index / (INPUTCOUNT + 1); + index %= (INPUTCOUNT + 1); + if (index == INPUTCOUNT) { objectCall1(value, Assign, pobj->out_data[pn]); } else { - objectCall1(value, Assign, pobj->in_data[pn * 4 + index]); + objectCall1(value, Assign, pobj->in_data[pn * INPUTCOUNT + index]); } return 0; } diff --git a/hdl4secell/verilog/hdl4secell.v b/hdl4secell/verilog/hdl4secell.v index 5afdda135f73485a0b7357addfdc5cb95ecc18a0..7a339addca9fa773e9c2c9a85019031976333218 100644 --- a/hdl4secell/verilog/hdl4secell.v +++ b/hdl4secell/verilog/hdl4secell.v @@ -304,6 +304,7 @@ module hdl4se_ram1p #(parameter WIDTH=8, ADDRWIDTH=8) ( input wClk, + input wWrite, input [ADDRWIDTH-1:0] bWriteAddr, input [WIDTH-1:0] bWriteData, input [ADDRWIDTH-1:0] bReadAddr, @@ -320,10 +321,12 @@ module hdl4se_ram2p #(parameter WIDTH=8, ADDRWIDTH=8) ( input wClk, + input wWrite1, input [ADDRWIDTH-1:0] bWriteAddr1, input [WIDTH-1:0] bWriteData1, input [ADDRWIDTH-1:0] bReadAddr1, output[WIDTH-1:0] bReadData1, + input wWrite2, input [ADDRWIDTH-1:0] bWriteAddr2, input [WIDTH-1:0] bWriteData2, input [ADDRWIDTH-1:0] bReadAddr2, diff --git a/testparser/main.c b/testparser/main.c index 398e8f3918a9da58a780fd24d0f09c16937d2e36..5cc7737491a09a148707e0abda45766d04b8f3a6 100644 --- a/testparser/main.c +++ b/testparser/main.c @@ -42,7 +42,7 @@ int main(int argc, char* argv[]) #if TERRIS if (argc < 2) - objectCall2(p, SetFile, "D:\\gitwork\\hdl4se\\examples\\terris\\verilog\\main_1.v", 0); + objectCall2(p, SetFile, "D:\\gitwork\\hdl4se\\examples\\terris\\verilog\\main_2.v", 0); else objectCall2(p, SetFile, argv[1], 0); pDumpFile = fopen("D:\\gitwork\\hdl4se\\examples\\terris\\verilog\\main_asm.v", "w");