/* ** 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_riscv_ram8k.c 202108250608: rxh, initial version */ #include "stdlib.h" #include "stdio.h" #include "object.h" #include "dlist.h" #include "string.h" #include "stdarg.h" #include "bignumber.h" #include "hdl4secell.h" #include "hdl4se_riscv.h" #ifdef WIN32 #define DATADIR "d:/gitwork/hdl4se/examples/hdl4se_riscv/" #else #define DATADIR "/media/raoxianhong/_dde_data/gitwork/hdl4se/examples/hdl4se_riscv/" #endif #define riscv_ram_MODULE_VERSION_STRING "0.4.0-20210825.0610 RISCV RAM cell" #define riscv_ram_MODULE_CLSID CLSID_HDL4SE_RISCV_RAM #define M_ID(id) riscv_ram##id /* 跟altera生成的端口一致 module ram8kb ( address, byteena, clock, data, wren, q); input [10:0] address; input [3:0] byteena; input clock; input [31:0] data; input wren; output [31:0] q; `ifndef ALTERA_RESERVED_QIS // synopsys translate_off `endif tri1 [3:0] byteena; tri1 clock; `ifndef ALTERA_RESERVED_QIS // synopsys translate_on `endif endmodule */ IDLIST VID(address), VID(byteena), VID(clock), VID(data), VID(wren), VID(q), VID(lastaddr), END_IDLIST MODULE_DECLARE(riscv_ram) unsigned int* ram; unsigned int ramaddr; unsigned int ramwrdata; unsigned int ramwren; unsigned int rambyteena; END_MODULE_DECLARE(riscv_ram) DEFINE_FUNC(riscv_ram_gen_q, "address, byteena, data, wren, lastaddr") { unsigned int lastaddr; lastaddr = vget(lastaddr); if (lastaddr < RAMSIZE) vput(q, pobj->ram[vget(lastaddr)]); else vput(q, 0xdeadbeef); } END_DEFINE_FUNC DEFINE_FUNC(riscv_ram_clktick, "") { pobj->ramwren = vget(wren); pobj->ramwrdata = vget(data); pobj->rambyteena = vget(byteena); pobj->ramaddr = vget(address); vput(lastaddr, vget(address)); } END_DEFINE_FUNC DEFINE_FUNC(riscv_ram_deinit, "") { if (pobj->ram != NULL) free(pobj->ram); } END_DEFINE_FUNC DEFINE_FUNC(riscv_ram_setup, "") { if (pobj->ramwren) { unsigned int mask = (pobj->rambyteena & 1 ? 0x000000ff : 0) | (pobj->rambyteena & 2 ? 0x0000ff00 : 0) | (pobj->rambyteena & 4 ? 0x00ff0000 : 0) | (pobj->rambyteena & 8 ? 0xff000000 : 0); if (pobj->ramaddr < RAMSIZE) pobj->ram[pobj->ramaddr] = (pobj->ram[pobj->ramaddr] & (~mask)) | (pobj->ramwrdata & mask); } pobj->ramwren = 0; } END_DEFINE_FUNC static int loadExecImage(unsigned char* data, int maxlen) { unsigned int addr; FILE* pFile = fopen(DATADIR"test_code/test.cod", "rt"); if (pFile == NULL) { printf("File %s can not open\n", DATADIR"test_code/test.cod"); exit(-1); } addr = 0; while (!feof(pFile)) { char line[256]; fgets(line, 256, pFile); if (strlen(line) < 2) break; if (line[0] == '@') { sscanf(line + 1, "%08x", &addr); } else { int len; int i; unsigned int temp[16]; if (addr >= maxlen - 16) { printf("loadExecImage failed, address [%08x] overflow\n", addr); exit(-5); } len = sscanf(line, "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", &temp[0], &temp[1], &temp[2], &temp[3], &temp[4], &temp[5], &temp[6], &temp[7], &temp[8], &temp[9], &temp[10], &temp[11], &temp[12], &temp[13], &temp[14], &temp[15]); for (i = 0; i < len; i++) data[addr + i] = temp[i]; addr += len; } } fclose(pFile); pFile = fopen(DATADIR"test_code/test.mif", "wt"); fprintf(pFile, "DEPTH = %d;\n", RAMSIZE); fprintf(pFile, "WIDTH = 32;\n"); fprintf(pFile, "ADDRESS_RADIX = HEX;\n"); fprintf(pFile, "DATA_RADIX = HEX;\n"); fprintf(pFile, "CONTENT\n"); fprintf(pFile, "BEGIN\n"); for (addr = 0; addr < RAMSIZE; addr++) { fprintf(pFile, "%04X : %08X;\n", addr, *(unsigned int *)(data + addr * 4)); } fprintf(pFile, "END;\n"); fclose(pFile); pFile = fopen(DATADIR"de1/test.mif", "wt"); fprintf(pFile, "DEPTH = %d;\n", RAMSIZE); fprintf(pFile, "WIDTH = 32;\n"); fprintf(pFile, "ADDRESS_RADIX = HEX;\n"); fprintf(pFile, "DATA_RADIX = HEX;\n"); fprintf(pFile, "CONTENT\n"); fprintf(pFile, "BEGIN\n"); for (addr = 0; addr < RAMSIZE; addr++) { fprintf(pFile, "%04X : %08X;\n", addr, *(unsigned int*)(data + addr * 4)); } fprintf(pFile, "END;\n"); fclose(pFile); } MODULE_INIT(riscv_ram) pobj->ram = malloc(RAMSIZE * 4); loadExecImage(pobj->ram, RAMSIZE * 4); pobj->ramwren = 0; PORT_IN(clock, 1); PORT_IN(wren, 1); PORT_IN(address, 30); PORT_IN(data, 32); PORT_IN(byteena, 4); GPORT_OUT(q, 32, riscv_ram_gen_q); REG(lastaddr, 30); CLKTICK_FUNC(riscv_ram_clktick); SETUP_FUNC(riscv_ram_setup); DEINIT_FUNC(riscv_ram_deinit); END_MODULE_INIT(riscv_ram)