diff --git a/.gitignore b/.gitignore index 72290cb..89987b1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,48 @@ -configs/snapshots -work -obj_dir -*.vcd -*.csv -*.hex +# Exclude/Ignore file for git *.log +RCS +*~ +.*.swp +.*.swo +.DS_Store +*.[oa] +RCS/ +snapshots/ +.zenconfig +workspace/ +workspace/work +# These are derived files +configs/common_defines.vh +configs/pd_defines.vh +configs/perl_configs.pl +configs/whisper.json +verif/diags/env/defines.h +design/include/pic_map_auto.h +design/include/pic_ctrl_verilator_unroll.sv +#codegenerators files +tools/codegenerators/AAPG/randomSeed.txt +tools/codegenerators/AAPG/aapg.pyc +tools/codegenerators/AAPG/baseInstructions.pyc +tools/codegenerators/AAPG/commonStuff.pyc +tools/codegenerators/AAPG/commonVar.pyc +tools/codegenerators/AAPG/config.pyc +tools/codegenerators/AAPG/opcodes.pyc +tools/codegenerators/AAPG/parseObjdump.pyc +tools/codegenerators/AAPG/result +tools/codegenerators/AAPG/standardExtensions.pyc +tools/codegenerators/csmith_run/platform.info +tools/codegenerators/csmith_run/syscalls.echx1 +tools/codegenerators/csmith_run/syscalls.spike +tools/codegenerators/csmith_run/testdir_* +tools/codegenerators/riscv-torture/generator/target +tools/codegenerators/riscv-torture/project/target +tools/codegenerators/riscv-torture/testrun/target +verif/diags/C/csmith +verif/diags/reg +verif/vip/sdvt_ahb +tools/codegenerators/riscv-torture/output +tools/codegenerators/AAPG/randomSeed.txt +unit_level_testbench/pic/workspace/simulation/sim +tools/codegenerators/AAPGV2/swerv/asm/out* +tools/codegenerators/AAPGV2/swerv/bin/out* +tools/codegenerators/AAPGV2/swerv/objdump/out* diff --git a/configs/snapshots/default/common_defines.vh b/configs/snapshots/default/common_defines.vh deleted file mode 100644 index 6a5c3c2..0000000 --- a/configs/snapshots/default/common_defines.vh +++ /dev/null @@ -1,170 +0,0 @@ -// NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE -// This is an automatically generated file by joseph.rahmeh on Tue Oct 15 13:13:16 PDT 2019 -// -// cmd: swerv -snapshot=default -ahb_lite -// -`define RV_INST_ACCESS_MASK5 'hffffffff -`define RV_DATA_ACCESS_ENABLE4 1'h0 -`define RV_INST_ACCESS_ENABLE3 1'h0 -`define RV_INST_ACCESS_ENABLE0 1'h0 -`define RV_INST_ACCESS_MASK3 'hffffffff -`define RV_DATA_ACCESS_ENABLE5 1'h0 -`define RV_DATA_ACCESS_MASK5 'hffffffff -`define RV_DATA_ACCESS_ADDR3 'h00000000 -`define RV_INST_ACCESS_ENABLE7 1'h0 -`define RV_DATA_ACCESS_ADDR6 'h00000000 -`define RV_INST_ACCESS_MASK7 'hffffffff -`define RV_INST_ACCESS_ENABLE6 1'h0 -`define RV_INST_ACCESS_ENABLE5 1'h0 -`define RV_DATA_ACCESS_ADDR4 'h00000000 -`define RV_DATA_ACCESS_ADDR7 'h00000000 -`define RV_DATA_ACCESS_MASK3 'hffffffff -`define RV_INST_ACCESS_MASK4 'hffffffff -`define RV_DATA_ACCESS_ADDR1 'h00000000 -`define RV_INST_ACCESS_ADDR4 'h00000000 -`define RV_INST_ACCESS_ADDR3 'h00000000 -`define RV_DATA_ACCESS_ENABLE1 1'h0 -`define RV_DATA_ACCESS_ADDR0 'h00000000 -`define RV_DATA_ACCESS_MASK0 'hffffffff -`define RV_DATA_ACCESS_MASK6 'hffffffff -`define RV_INST_ACCESS_ADDR7 'h00000000 -`define RV_INST_ACCESS_MASK0 'hffffffff -`define RV_DATA_ACCESS_ADDR5 'h00000000 -`define RV_DATA_ACCESS_ADDR2 'h00000000 -`define RV_DATA_ACCESS_MASK4 'hffffffff -`define RV_DATA_ACCESS_MASK1 'hffffffff -`define RV_INST_ACCESS_ADDR0 'h00000000 -`define RV_INST_ACCESS_ADDR2 'h00000000 -`define RV_DATA_ACCESS_ENABLE0 1'h0 -`define RV_DATA_ACCESS_ENABLE2 1'h0 -`define RV_DATA_ACCESS_ENABLE7 1'h0 -`define RV_INST_ACCESS_ENABLE4 1'h0 -`define RV_DATA_ACCESS_MASK7 'hffffffff -`define RV_INST_ACCESS_ADDR5 'h00000000 -`define RV_INST_ACCESS_ENABLE1 1'h0 -`define RV_DATA_ACCESS_MASK2 'hffffffff -`define RV_INST_ACCESS_MASK6 'hffffffff -`define RV_DATA_ACCESS_ENABLE3 1'h0 -`define RV_INST_ACCESS_ADDR6 'h00000000 -`define RV_INST_ACCESS_MASK2 'hffffffff -`define RV_INST_ACCESS_ENABLE2 1'h0 -`define RV_DATA_ACCESS_ENABLE6 1'h0 -`define RV_INST_ACCESS_ADDR1 'h00000000 -`define RV_INST_ACCESS_MASK1 'hffffffff -`define RV_DEC_INSTBUF_DEPTH 4 -`define RV_DMA_BUF_DEPTH 4 -`define RV_LSU_NUM_NBLOAD 8 -`define RV_LSU_STBUF_DEPTH 8 -`define RV_LSU_NUM_NBLOAD_WIDTH 3 -`define RV_IFU_BUS_TAG 3 -`define RV_LSU_BUS_TAG 4 -`define RV_SB_BUS_TAG 1 -`define RV_DMA_BUS_TAG 1 -`define RV_DCCM_WIDTH_BITS 2 -`define RV_DCCM_REGION 4'hf -`define RV_DCCM_RESERVED 'h1000 -`define RV_DCCM_SIZE 64 -`define RV_DCCM_DATA_WIDTH 32 -`define RV_DCCM_NUM_BANKS_8 -`define RV_DCCM_FDATA_WIDTH 39 -`define RV_DCCM_BYTE_WIDTH 4 -`define RV_DCCM_DATA_CELL ram_2048x39 -`define RV_DCCM_ENABLE 1 -`define RV_DCCM_BITS 16 -`define RV_DCCM_OFFSET 28'h40000 -`define RV_DCCM_ECC_WIDTH 7 -`define RV_DCCM_SIZE_64 -`define RV_DCCM_ROWS 2048 -`define RV_DCCM_BANK_BITS 3 -`define RV_DCCM_NUM_BANKS 8 -`define RV_DCCM_INDEX_BITS 11 -`define RV_LSU_SB_BITS 16 -`define RV_DCCM_EADR 32'hf004ffff -`define RV_DCCM_SADR 32'hf0040000 -`define RV_RESET_VEC 'h80000000 -`define RV_RET_STACK_SIZE 4 -`define RV_XLEN 32 -`define RV_TARGET default -`define RV_BTB_BTAG_FOLD 1 -`define RV_BTB_INDEX3_HI 9 -`define RV_BTB_INDEX1_LO 4 -`define RV_BTB_ADDR_HI 5 -`define RV_BTB_ADDR_LO 4 -`define RV_BTB_INDEX1_HI 5 -`define RV_BTB_INDEX2_HI 7 -`define RV_BTB_INDEX2_LO 6 -`define RV_BTB_ARRAY_DEPTH 4 -`define RV_BTB_BTAG_SIZE 9 -`define RV_BTB_SIZE 32 -`define RV_BTB_INDEX3_LO 8 -`define RV_ICCM_NUM_BANKS 8 -`define RV_ICCM_BITS 19 -`define RV_ICCM_BANK_BITS 3 -`define RV_ICCM_ROWS 16384 -`define RV_ICCM_OFFSET 10'he000000 -`define RV_ICCM_REGION 4'he -`define RV_ICCM_SADR 32'hee000000 -`define RV_ICCM_RESERVED 'h1000 -`define RV_ICCM_DATA_CELL ram_16384x39 -`define RV_ICCM_INDEX_BITS 14 -`define RV_ICCM_NUM_BANKS_8 -`define RV_ICCM_SIZE 512 -`define RV_ICCM_EADR 32'hee07ffff -`define RV_ICCM_SIZE_512 -`define RV_ICACHE_SIZE 16 -`define RV_ICACHE_TAG_HIGH 12 -`define RV_ICACHE_IC_ROWS 256 -`define RV_ICACHE_TADDR_HIGH 5 -`define RV_ICACHE_TAG_LOW 6 -`define RV_ICACHE_TAG_CELL ram_64x21 -`define RV_ICACHE_IC_DEPTH 8 -`define RV_ICACHE_IC_INDEX 8 -`define RV_ICACHE_ENABLE 1 -`define RV_ICACHE_DATA_CELL ram_256x34 -`define RV_ICACHE_TAG_DEPTH 64 -`define RV_EXTERNAL_PROG 'hb0000000 -`define RV_EXTERNAL_DATA_1 'h00000000 -`define RV_DEBUG_SB_MEM 'hb0580000 -`define RV_EXTERNAL_DATA 'hc0580000 -`define RV_SERIALIO 'hd0580000 -`define RV_NMI_VEC 'h11110000 -`define RV_BHT_HASH_STRING {ghr[3:2] ^ {ghr[3+1], {4-1-2{1'b0} } },hashin[5:4]^ghr[2-1:0]} -`define RV_BHT_ADDR_HI 7 -`define RV_BHT_GHR_RANGE 4:0 -`define RV_BHT_GHR_SIZE 5 -`define RV_BHT_GHR_PAD2 fghr[4:3],2'b0 -`define RV_BHT_SIZE 128 -`define RV_BHT_ADDR_LO 4 -`define RV_BHT_ARRAY_DEPTH 16 -`define RV_BHT_GHR_PAD fghr[4],3'b0 -`define RV_NUMIREGS 32 -`define RV_PIC_BITS 15 -`define RV_PIC_REGION 4'hf -`define RV_PIC_INT_WORDS 1 -`define RV_PIC_TOTAL_INT_PLUS1 9 -`define RV_PIC_MEIP_OFFSET 'h1000 -`define RV_PIC_BASE_ADDR 32'hf00c0000 -`define RV_PIC_MEIGWCTRL_OFFSET 'h4000 -`define RV_PIC_MEIPL_OFFSET 'h0000 -`define RV_PIC_TOTAL_INT 8 -`define RV_PIC_SIZE 32 -`define RV_PIC_MEIE_OFFSET 'h2000 -`define RV_PIC_OFFSET 10'hc0000 -`define RV_PIC_MEIPT_OFFSET 'h3004 -`define RV_PIC_MPICCFG_OFFSET 'h3000 -`define RV_PIC_MEIGWCLR_OFFSET 'h5000 -`define CLOCK_PERIOD 100 -`define CPU_TOP `RV_TOP.swerv -`define TOP tb_top -`define RV_BUILD_AHB_LITE 1 -`define RV_TOP `TOP.rvtop -`define DATAWIDTH 64 -`define RV_STERR_ROLLBACK 0 -`define RV_EXT_ADDRWIDTH 32 -`define RV_EXT_DATAWIDTH 64 -`define SDVT_AHB 1 -`define RV_LDERR_ROLLBACK 1 -`define ASSERT_ON -`define TEC_RV_ICG clockhdr -`define REGWIDTH 32 -`undef ASSERT_ON diff --git a/configs/snapshots/default/defines.h b/configs/snapshots/default/defines.h deleted file mode 100644 index 6abfd1a..0000000 --- a/configs/snapshots/default/defines.h +++ /dev/null @@ -1,132 +0,0 @@ -// NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE -// This is an automatically generated file by joseph.rahmeh on Tue Oct 15 13:13:16 PDT 2019 -// -// cmd: swerv -snapshot=default -ahb_lite -// -#define RV_INST_ACCESS_MASK5 0xffffffff -#define RV_DATA_ACCESS_ENABLE4 0x0 -#define RV_INST_ACCESS_ENABLE3 0x0 -#define RV_INST_ACCESS_ENABLE0 0x0 -#define RV_INST_ACCESS_MASK3 0xffffffff -#define RV_DATA_ACCESS_ENABLE5 0x0 -#define RV_DATA_ACCESS_MASK5 0xffffffff -#define RV_DATA_ACCESS_ADDR3 0x00000000 -#define RV_INST_ACCESS_ENABLE7 0x0 -#define RV_DATA_ACCESS_ADDR6 0x00000000 -#define RV_INST_ACCESS_MASK7 0xffffffff -#define RV_INST_ACCESS_ENABLE6 0x0 -#define RV_INST_ACCESS_ENABLE5 0x0 -#define RV_DATA_ACCESS_ADDR4 0x00000000 -#define RV_DATA_ACCESS_ADDR7 0x00000000 -#define RV_DATA_ACCESS_MASK3 0xffffffff -#define RV_INST_ACCESS_MASK4 0xffffffff -#define RV_DATA_ACCESS_ADDR1 0x00000000 -#define RV_INST_ACCESS_ADDR4 0x00000000 -#define RV_INST_ACCESS_ADDR3 0x00000000 -#define RV_DATA_ACCESS_ENABLE1 0x0 -#define RV_DATA_ACCESS_ADDR0 0x00000000 -#define RV_DATA_ACCESS_MASK0 0xffffffff -#define RV_DATA_ACCESS_MASK6 0xffffffff -#define RV_INST_ACCESS_ADDR7 0x00000000 -#define RV_INST_ACCESS_MASK0 0xffffffff -#define RV_DATA_ACCESS_ADDR5 0x00000000 -#define RV_DATA_ACCESS_ADDR2 0x00000000 -#define RV_DATA_ACCESS_MASK4 0xffffffff -#define RV_DATA_ACCESS_MASK1 0xffffffff -#define RV_INST_ACCESS_ADDR0 0x00000000 -#define RV_INST_ACCESS_ADDR2 0x00000000 -#define RV_DATA_ACCESS_ENABLE0 0x0 -#define RV_DATA_ACCESS_ENABLE2 0x0 -#define RV_DATA_ACCESS_ENABLE7 0x0 -#define RV_INST_ACCESS_ENABLE4 0x0 -#define RV_DATA_ACCESS_MASK7 0xffffffff -#define RV_INST_ACCESS_ADDR5 0x00000000 -#define RV_INST_ACCESS_ENABLE1 0x0 -#define RV_DATA_ACCESS_MASK2 0xffffffff -#define RV_INST_ACCESS_MASK6 0xffffffff -#define RV_DATA_ACCESS_ENABLE3 0x0 -#define RV_INST_ACCESS_ADDR6 0x00000000 -#define RV_INST_ACCESS_MASK2 0xffffffff -#define RV_INST_ACCESS_ENABLE2 0x0 -#define RV_DATA_ACCESS_ENABLE6 0x0 -#define RV_INST_ACCESS_ADDR1 0x00000000 -#define RV_INST_ACCESS_MASK1 0xffffffff -#define RV_IFU_BUS_TAG 3 -#define RV_LSU_BUS_TAG 4 -#define RV_SB_BUS_TAG 1 -#define RV_DMA_BUS_TAG 1 -#define RV_DCCM_WIDTH_BITS 2 -#define RV_DCCM_REGION 0xf -#define RV_DCCM_RESERVED 0x1000 -#define RV_DCCM_SIZE 64 -#define RV_DCCM_DATA_WIDTH 32 -#define RV_DCCM_NUM_BANKS_8 -#define RV_DCCM_FDATA_WIDTH 39 -#define RV_DCCM_BYTE_WIDTH 4 -#define RV_DCCM_DATA_CELL ram_2048x39 -#define RV_DCCM_ENABLE 1 -#define RV_DCCM_BITS 16 -#define RV_DCCM_OFFSET 0x40000 -#define RV_DCCM_ECC_WIDTH 7 -#define RV_DCCM_SIZE_64 -#define RV_DCCM_ROWS 2048 -#define RV_DCCM_BANK_BITS 3 -#define RV_DCCM_NUM_BANKS 8 -#define RV_DCCM_INDEX_BITS 11 -#define RV_LSU_SB_BITS 16 -#define RV_DCCM_EADR 0xf004ffff -#define RV_DCCM_SADR 0xf0040000 -#ifndef RV_RESET_VEC -#define RV_RESET_VEC 0x80000000 -#endif -#define RV_XLEN 32 -#define RV_TARGET default -#define RV_ICCM_NUM_BANKS 8 -#define RV_ICCM_BITS 19 -#define RV_ICCM_BANK_BITS 3 -#define RV_ICCM_ROWS 16384 -#define RV_ICCM_OFFSET 0xe000000 -#define RV_ICCM_REGION 0xe -#define RV_ICCM_SADR 0xee000000 -#define RV_ICCM_RESERVED 0x1000 -#define RV_ICCM_DATA_CELL ram_16384x39 -#define RV_ICCM_INDEX_BITS 14 -#define RV_ICCM_NUM_BANKS_8 -#define RV_ICCM_SIZE 512 -#define RV_ICCM_EADR 0xee07ffff -#define RV_ICCM_SIZE_512 -#define RV_EXTERNAL_PROG 0xb0000000 -#define RV_EXTERNAL_DATA_1 0x00000000 -#define RV_DEBUG_SB_MEM 0xb0580000 -#define RV_EXTERNAL_DATA 0xc0580000 -#define RV_SERIALIO 0xd0580000 -#ifndef RV_NMI_VEC -#define RV_NMI_VEC 0x11110000 -#endif -#define RV_PIC_BITS 15 -#define RV_PIC_REGION 0xf -#define RV_PIC_INT_WORDS 1 -#define RV_PIC_TOTAL_INT_PLUS1 9 -#define RV_PIC_MEIP_OFFSET 0x1000 -#define RV_PIC_BASE_ADDR 0xf00c0000 -#define RV_PIC_MEIGWCTRL_OFFSET 0x4000 -#define RV_PIC_MEIPL_OFFSET 0x0000 -#define RV_PIC_TOTAL_INT 8 -#define RV_PIC_SIZE 32 -#define RV_PIC_MEIE_OFFSET 0x2000 -#define RV_PIC_OFFSET 0xc0000 -#define RV_PIC_MEIPT_OFFSET 0x3004 -#define RV_PIC_MPICCFG_OFFSET 0x3000 -#define RV_PIC_MEIGWCLR_OFFSET 0x5000 -#define CLOCK_PERIOD 100 -#define CPU_TOP `RV_TOP.swerv -#define TOP tb_top -#define RV_BUILD_AHB_LITE 1 -#define RV_TOP `TOP.rvtop -#define DATAWIDTH 64 -#define RV_STERR_ROLLBACK 0 -#define RV_EXT_ADDRWIDTH 32 -#define RV_EXT_DATAWIDTH 64 -#define SDVT_AHB 1 -#define RV_LDERR_ROLLBACK 1 -#define ASSERT_ON diff --git a/configs/snapshots/default/pd_defines.vh b/configs/snapshots/default/pd_defines.vh deleted file mode 100644 index 93bcc71..0000000 --- a/configs/snapshots/default/pd_defines.vh +++ /dev/null @@ -1,11 +0,0 @@ -// NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE -// This is an automatically generated file by joseph.rahmeh on Tue Oct 15 13:13:16 PDT 2019 -// -// cmd: swerv -snapshot=default -ahb_lite -// - -`include "common_defines.vh" -`undef ASSERT_ON -`undef TEC_RV_ICG -`define TEC_RV_ICG CKLNQD12BWP35P140 -`define PHYSICAL 1 diff --git a/configs/snapshots/default/perl_configs.pl b/configs/snapshots/default/perl_configs.pl deleted file mode 100644 index 199b3eb..0000000 --- a/configs/snapshots/default/perl_configs.pl +++ /dev/null @@ -1,566 +0,0 @@ -# NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE -# This is an automatically generated file by joseph.rahmeh on Tue Oct 15 13:13:16 PDT 2019 -# -# cmd: swerv -snapshot=default -ahb_lite -# -# To use this in a perf script, use 'require $RV_ROOT/configs/config.pl' -# Reference the hash via $config{name}.. - - -%config = ( - 'protection' => { - 'inst_access_mask5' => '0xffffffff', - 'data_access_enable4' => '0x0', - 'inst_access_enable3' => '0x0', - 'inst_access_enable0' => '0x0', - 'inst_access_mask3' => '0xffffffff', - 'data_access_enable5' => '0x0', - 'data_access_mask5' => '0xffffffff', - 'data_access_addr3' => '0x00000000', - 'inst_access_enable7' => '0x0', - 'data_access_addr6' => '0x00000000', - 'inst_access_mask7' => '0xffffffff', - 'inst_access_enable6' => '0x0', - 'inst_access_enable5' => '0x0', - 'data_access_addr4' => '0x00000000', - 'data_access_addr7' => '0x00000000', - 'data_access_mask3' => '0xffffffff', - 'inst_access_mask4' => '0xffffffff', - 'data_access_addr1' => '0x00000000', - 'inst_access_addr4' => '0x00000000', - 'inst_access_addr3' => '0x00000000', - 'data_access_enable1' => '0x0', - 'data_access_addr0' => '0x00000000', - 'data_access_mask0' => '0xffffffff', - 'data_access_mask6' => '0xffffffff', - 'inst_access_addr7' => '0x00000000', - 'inst_access_mask0' => '0xffffffff', - 'data_access_addr5' => '0x00000000', - 'data_access_addr2' => '0x00000000', - 'data_access_mask4' => '0xffffffff', - 'data_access_mask1' => '0xffffffff', - 'inst_access_addr0' => '0x00000000', - 'inst_access_addr2' => '0x00000000', - 'data_access_enable0' => '0x0', - 'data_access_enable2' => '0x0', - 'data_access_enable7' => '0x0', - 'inst_access_enable4' => '0x0', - 'data_access_mask7' => '0xffffffff', - 'inst_access_addr5' => '0x00000000', - 'inst_access_enable1' => '0x0', - 'data_access_mask2' => '0xffffffff', - 'inst_access_mask6' => '0xffffffff', - 'data_access_enable3' => '0x0', - 'inst_access_addr6' => '0x00000000', - 'inst_access_mask2' => '0xffffffff', - 'inst_access_enable2' => '0x0', - 'data_access_enable6' => '0x0', - 'inst_access_addr1' => '0x00000000', - 'inst_access_mask1' => '0xffffffff' - }, - 'core' => { - 'dec_instbuf_depth' => '4', - 'dma_buf_depth' => '4', - 'lsu_num_nbload' => '8', - 'lsu_stbuf_depth' => '8', - 'lsu_num_nbload_width' => '3' - }, - 'bus' => { - 'ifu_bus_tag' => '3', - 'lsu_bus_tag' => 4, - 'sb_bus_tag' => '1', - 'dma_bus_tag' => '1' - }, - 'dccm' => { - 'dccm_width_bits' => 2, - 'dccm_region' => '0xf', - 'dccm_reserved' => '0x1000', - 'dccm_size' => 64, - 'dccm_data_width' => 32, - 'dccm_num_banks_8' => '', - 'dccm_fdata_width' => 39, - 'dccm_byte_width' => '4', - 'dccm_data_cell' => 'ram_2048x39', - 'dccm_enable' => '1', - 'dccm_bits' => 16, - 'dccm_offset' => '0x40000', - 'dccm_ecc_width' => 7, - 'dccm_size_64' => '', - 'dccm_rows' => '2048', - 'dccm_bank_bits' => 3, - 'dccm_num_banks' => '8', - 'dccm_index_bits' => 11, - 'lsu_sb_bits' => 16, - 'dccm_eadr' => '0xf004ffff', - 'dccm_sadr' => '0xf0040000' - }, - 'reset_vec' => '0x80000000', - 'retstack' => { - 'ret_stack_size' => '4' - }, - 'triggers' => [ - { - 'poke_mask' => [ - '0x081818c7', - '0xffffffff', - '0x00000000' - ], - 'reset' => [ - '0x23e00000', - '0x00000000', - '0x00000000' - ], - 'mask' => [ - '0x081818c7', - '0xffffffff', - '0x00000000' - ] - }, - { - 'poke_mask' => [ - '0x081818c7', - '0xffffffff', - '0x00000000' - ], - 'reset' => [ - '0x23e00000', - '0x00000000', - '0x00000000' - ], - 'mask' => [ - '0x081818c7', - '0xffffffff', - '0x00000000' - ] - }, - { - 'poke_mask' => [ - '0x081818c7', - '0xffffffff', - '0x00000000' - ], - 'reset' => [ - '0x23e00000', - '0x00000000', - '0x00000000' - ], - 'mask' => [ - '0x081818c7', - '0xffffffff', - '0x00000000' - ] - }, - { - 'poke_mask' => [ - '0x081818c7', - '0xffffffff', - '0x00000000' - ], - 'reset' => [ - '0x23e00000', - '0x00000000', - '0x00000000' - ], - 'mask' => [ - '0x081818c7', - '0xffffffff', - '0x00000000' - ] - } - ], - 'xlen' => 32, - 'verilator' => '', - 'target' => 'default', - 'max_mmode_perf_event' => '50', - 'btb' => { - 'btb_btag_fold' => 1, - 'btb_index3_hi' => 9, - 'btb_index1_lo' => '4', - 'btb_addr_hi' => 5, - 'btb_addr_lo' => '4', - 'btb_index1_hi' => 5, - 'btb_index2_hi' => 7, - 'btb_index2_lo' => 6, - 'btb_array_depth' => 4, - 'btb_btag_size' => 9, - 'btb_size' => 32, - 'btb_index3_lo' => 8 - }, - 'iccm' => { - 'iccm_num_banks' => '8', - 'iccm_bits' => 19, - 'iccm_bank_bits' => 3, - 'iccm_rows' => '16384', - 'iccm_offset' => '0xe000000', - 'iccm_region' => '0xe', - 'iccm_sadr' => '0xee000000', - 'iccm_reserved' => '0x1000', - 'iccm_data_cell' => 'ram_16384x39', - 'iccm_index_bits' => 14, - 'iccm_num_banks_8' => '', - 'iccm_size' => 512, - 'iccm_eadr' => '0xee07ffff', - 'iccm_size_512' => '' - }, - 'icache' => { - 'icache_size' => 16, - 'icache_tag_high' => 12, - 'icache_ic_rows' => '256', - 'icache_taddr_high' => 5, - 'icache_tag_low' => '6', - 'icache_tag_cell' => 'ram_64x21', - 'icache_ic_depth' => 8, - 'icache_ic_index' => 8, - 'icache_enable' => '1', - 'icache_data_cell' => 'ram_256x34', - 'icache_tag_depth' => 64 - }, - 'physical' => '1', - 'memmap' => { - 'external_prog' => '0xb0000000', - 'external_data_1' => '0x00000000', - 'debug_sb_mem' => '0xb0580000', - 'external_data' => '0xc0580000', - 'serialio' => '0xd0580000' - }, - 'nmi_vec' => '0x11110000', - 'num_mmode_perf_regs' => '4', - 'bht' => { - 'bht_hash_string' => '{ghr[3:2] ^ {ghr[3+1], {4-1-2{1\'b0} } },hashin[5:4]^ghr[2-1:0]}', - 'bht_addr_hi' => 7, - 'bht_ghr_range' => '4:0', - 'bht_ghr_size' => 5, - 'bht_ghr_pad2' => 'fghr[4:3],2\'b0', - 'bht_size' => 128, - 'bht_addr_lo' => '4', - 'bht_array_depth' => 16, - 'bht_ghr_pad' => 'fghr[4],3\'b0' - }, - 'numiregs' => '32', - 'even_odd_trigger_chains' => 'true', - 'pic' => { - 'pic_bits' => 15, - 'pic_region' => '0xf', - 'pic_int_words' => 1, - 'pic_total_int_plus1' => 9, - 'pic_meip_offset' => '0x1000', - 'pic_base_addr' => '0xf00c0000', - 'pic_meigwctrl_offset' => '0x4000', - 'pic_meipl_offset' => '0x0000', - 'pic_total_int' => 8, - 'pic_size' => 32, - 'pic_meie_offset' => '0x2000', - 'pic_offset' => '0xc0000', - 'pic_meipt_offset' => '0x3004', - 'pic_mpiccfg_offset' => '0x3000', - 'pic_meigwclr_offset' => '0x5000' - }, - 'testbench' => { - 'clock_period' => '100', - 'CPU_TOP' => '`RV_TOP.swerv', - 'TOP' => 'tb_top', - 'build_ahb_lite' => '1', - 'RV_TOP' => '`TOP.rvtop', - 'datawidth' => '64', - 'sterr_rollback' => '0', - 'ext_addrwidth' => '32', - 'ext_datawidth' => '64', - 'SDVT_AHB' => '1', - 'lderr_rollback' => '1', - 'assert_on' => '' - }, - 'tec_rv_icg' => 'clockhdr', - 'csr' => { - 'pmpaddr9' => { - 'exists' => 'false' - }, - 'dicad1' => { - 'reset' => '0x0', - 'number' => '0x7ca', - 'comment' => 'Cache diagnostics.', - 'debug' => 'true', - 'exists' => 'true', - 'mask' => '0x3' - }, - 'pmpcfg0' => { - 'exists' => 'false' - }, - 'mhpmcounter4h' => { - 'reset' => '0x0', - 'exists' => 'true', - 'mask' => '0xffffffff' - }, - 'dicago' => { - 'reset' => '0x0', - 'number' => '0x7cb', - 'comment' => 'Cache diagnostics.', - 'debug' => 'true', - 'exists' => 'true', - 'mask' => '0x0' - }, - 'mie' => { - 'reset' => '0x0', - 'exists' => 'true', - 'mask' => '0x40000888' - }, - 'misa' => { - 'reset' => '0x40001104', - 'exists' => 'true', - 'mask' => '0x0' - }, - 'mhpmcounter6h' => { - 'reset' => '0x0', - 'exists' => 'true', - 'mask' => '0xffffffff' - }, - 'meicpct' => { - 'reset' => '0x0', - 'number' => '0xbca', - 'comment' => 'External claim id/priority capture.', - 'exists' => 'true', - 'mask' => '0x0' - }, - 'mimpid' => { - 'reset' => '0x1', - 'exists' => 'true', - 'mask' => '0x0' - }, - 'mcpc' => { - 'reset' => '0x0', - 'number' => '0x7c2', - 'exists' => 'true', - 'mask' => '0x0' - }, - 'mhpmevent4' => { - 'reset' => '0x0', - 'exists' => 'true', - 'mask' => '0xffffffff' - }, - 'pmpaddr8' => { - 'exists' => 'false' - }, - 'pmpcfg3' => { - 'exists' => 'false' - }, - 'marchid' => { - 'reset' => '0x0000000b', - 'exists' => 'true', - 'mask' => '0x0' - }, - 'pmpaddr5' => { - 'exists' => 'false' - }, - 'mfdc' => { - 'reset' => '0x00070000', - 'number' => '0x7f9', - 'exists' => 'true', - 'mask' => '0x000707ff' - }, - 'mhpmevent6' => { - 'reset' => '0x0', - 'exists' => 'true', - 'mask' => '0xffffffff' - }, - 'mvendorid' => { - 'reset' => '0x45', - 'exists' => 'true', - 'mask' => '0x0' - }, - 'pmpaddr4' => { - 'exists' => 'false' - }, - 'dcsr' => { - 'poke_mask' => '0x00008dcc', - 'reset' => '0x40000003', - 'exists' => 'true', - 'mask' => '0x00008c04' - }, - 'cycle' => { - 'exists' => 'false' - }, - 'pmpaddr12' => { - 'exists' => 'false' - }, - 'pmpaddr3' => { - 'exists' => 'false' - }, - 'mhpmcounter3h' => { - 'reset' => '0x0', - 'exists' => 'true', - 'mask' => '0xffffffff' - }, - 'time' => { - 'exists' => 'false' - }, - 'meicidpl' => { - 'reset' => '0x0', - 'number' => '0xbcb', - 'comment' => 'External interrupt claim id priority level.', - 'exists' => 'true', - 'mask' => '0xf' - }, - 'pmpaddr14' => { - 'exists' => 'false' - }, - 'pmpaddr13' => { - 'exists' => 'false' - }, - 'pmpaddr1' => { - 'exists' => 'false' - }, - 'mhpmcounter6' => { - 'reset' => '0x0', - 'exists' => 'true', - 'mask' => '0xffffffff' - }, - 'dicad0' => { - 'reset' => '0x0', - 'number' => '0x7c9', - 'comment' => 'Cache diagnostics.', - 'debug' => 'true', - 'exists' => 'true', - 'mask' => '0xffffffff' - }, - 'meipt' => { - 'reset' => '0x0', - 'number' => '0xbc9', - 'comment' => 'External interrupt priority threshold.', - 'exists' => 'true', - 'mask' => '0xf' - }, - 'pmpaddr15' => { - 'exists' => 'false' - }, - 'mhpmcounter5' => { - 'reset' => '0x0', - 'exists' => 'true', - 'mask' => '0xffffffff' - }, - 'pmpcfg1' => { - 'exists' => 'false' - }, - 'pmpaddr10' => { - 'exists' => 'false' - }, - 'pmpaddr0' => { - 'exists' => 'false' - }, - 'pmpcfg2' => { - 'exists' => 'false' - }, - 'pmpaddr2' => { - 'exists' => 'false' - }, - 'mpmc' => { - 'reset' => '0x0', - 'number' => '0x7c6', - 'comment' => 'Core pause: Implemented as read only.', - 'exists' => 'true', - 'mask' => '0x0' - }, - 'dmst' => { - 'reset' => '0x0', - 'number' => '0x7c4', - 'comment' => 'Memory synch trigger: Flush caches in debug mode.', - 'debug' => 'true', - 'exists' => 'true', - 'mask' => '0x0' - }, - 'instret' => { - 'exists' => 'false' - }, - 'mhpmevent3' => { - 'reset' => '0x0', - 'exists' => 'true', - 'mask' => '0xffffffff' - }, - 'dicawics' => { - 'reset' => '0x0', - 'number' => '0x7c8', - 'comment' => 'Cache diagnostics.', - 'debug' => 'true', - 'exists' => 'true', - 'mask' => '0x0130fffc' - }, - 'mip' => { - 'poke_mask' => '0x40000888', - 'reset' => '0x0', - 'exists' => 'true', - 'mask' => '0x0' - }, - 'mhpmcounter5h' => { - 'reset' => '0x0', - 'exists' => 'true', - 'mask' => '0xffffffff' - }, - 'micect' => { - 'reset' => '0x0', - 'number' => '0x7f0', - 'exists' => 'true', - 'mask' => '0xffffffff' - }, - 'miccmect' => { - 'reset' => '0x0', - 'number' => '0x7f1', - 'exists' => 'true', - 'mask' => '0xffffffff' - }, - 'mhpmevent5' => { - 'reset' => '0x0', - 'exists' => 'true', - 'mask' => '0xffffffff' - }, - 'mhpmcounter3' => { - 'reset' => '0x0', - 'exists' => 'true', - 'mask' => '0xffffffff' - }, - 'pmpaddr6' => { - 'exists' => 'false' - }, - 'pmpaddr11' => { - 'exists' => 'false' - }, - 'mcgc' => { - 'poke_mask' => '0x000001ff', - 'reset' => '0x0', - 'number' => '0x7f8', - 'exists' => 'true', - 'mask' => '0x000001ff' - }, - 'mhpmcounter4' => { - 'reset' => '0x0', - 'exists' => 'true', - 'mask' => '0xffffffff' - }, - 'mdccmect' => { - 'reset' => '0x0', - 'number' => '0x7f2', - 'exists' => 'true', - 'mask' => '0xffffffff' - }, - 'pmpaddr7' => { - 'exists' => 'false' - }, - 'meicurpl' => { - 'reset' => '0x0', - 'number' => '0xbcc', - 'comment' => 'External interrupt current priority level.', - 'exists' => 'true', - 'mask' => '0xf' - }, - 'mstatus' => { - 'reset' => '0x1800', - 'exists' => 'true', - 'mask' => '0x88' - }, - 'tselect' => { - 'reset' => '0x0', - 'exists' => 'true', - 'mask' => '0x3' - } - }, - 'regwidth' => '32', - 'harts' => 1 - ); -1; diff --git a/configs/snapshots/default/pic_ctrl_verilator_unroll.sv b/configs/snapshots/default/pic_ctrl_verilator_unroll.sv deleted file mode 100644 index 8e15c4b..0000000 --- a/configs/snapshots/default/pic_ctrl_verilator_unroll.sv +++ /dev/null @@ -1,173 +0,0 @@ -// argv=9 -// TOTAL_INT=9 NUM_LEVELS=4 -`ifdef RV_PIC_2CYCLE -// LEVEL0 -logic [TOTAL_INT+2:0] [INTPRIORITY_BITS-1:0] level_intpend_w_prior_en_1; -logic [TOTAL_INT+2:0] [ID_BITS-1:0] level_intpend_id_1; - for (m=0; m<=(TOTAL_INT)/(2**(1)) ; m++) begin : COMPARE0 - if ( m == (TOTAL_INT)/(2**(1))) begin - assign level_intpend_w_prior_en_1[m+1] = '0 ; - assign level_intpend_id_1[m+1] = '0 ; - end - cmp_and_mux #( - .ID_BITS(ID_BITS), - .INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l1 ( - .a_id(level_intpend_id[0][2*m]), - .a_priority(level_intpend_w_prior_en[0][2*m]), - .b_id(level_intpend_id[0][2*m+1]), - .b_priority(level_intpend_w_prior_en[0][2*m+1]), - .out_id(level_intpend_id_1[m]), - .out_priority(level_intpend_w_prior_en_1[m])) ; - - end - -// LEVEL1 -logic [TOTAL_INT+2:0] [INTPRIORITY_BITS-1:0] level_intpend_w_prior_en_2; -logic [TOTAL_INT+2:0] [ID_BITS-1:0] level_intpend_id_2; - for (m=0; m<=(TOTAL_INT)/(2**(2)) ; m++) begin : COMPARE1 - if ( m == (TOTAL_INT)/(2**(2))) begin - assign level_intpend_w_prior_en_2[m+1] = '0 ; - assign level_intpend_id_2[m+1] = '0 ; - end - cmp_and_mux #( - .ID_BITS(ID_BITS), - .INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l2 ( - .a_id(level_intpend_id_1[2*m]), - .a_priority(level_intpend_w_prior_en_1[2*m]), - .b_id(level_intpend_id_1[2*m+1]), - .b_priority(level_intpend_w_prior_en_1[2*m+1]), - .out_id(level_intpend_id_2[m]), - .out_priority(level_intpend_w_prior_en_2[m])) ; - - end - -for (i=0; i<=TOTAL_INT/2**(NUM_LEVELS/2) ; i++) begin : MIDDLE_FLOPS - rvdff #(INTPRIORITY_BITS) level2_intpend_prior_reg (.*, .din (level_intpend_w_prior_en_2[i]), .dout(l2_intpend_w_prior_en_ff[i]), .clk(active_clk)); - rvdff #(ID_BITS) level2_intpend_id_reg (.*, .din (level_intpend_id_2[i]), .dout(l2_intpend_id_ff[i]), .clk(active_clk)); -end -// LEVEL2 -logic [TOTAL_INT+2:0] [INTPRIORITY_BITS-1:0] levelx_intpend_w_prior_en_3; -logic [TOTAL_INT+2:0] [ID_BITS-1:0] levelx_intpend_id_3; - for (m=0; m<=(TOTAL_INT)/(2**(3)) ; m++) begin : COMPARE2 - if ( m == (TOTAL_INT)/(2**(3))) begin - assign levelx_intpend_w_prior_en_3[m+1] = '0 ; - assign levelx_intpend_id_3[m+1] = '0 ; - end - cmp_and_mux #( - .ID_BITS(ID_BITS), - .INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l3 ( - .a_id(levelx_intpend_id[2][2*m]), - .a_priority(levelx_intpend_w_prior_en[2][2*m]), - .b_id(levelx_intpend_id[2][2*m+1]), - .b_priority(levelx_intpend_w_prior_en[2][2*m+1]), - .out_id(levelx_intpend_id_3[m]), - .out_priority(levelx_intpend_w_prior_en_3[m])) ; - - end - -// LEVEL3 -logic [TOTAL_INT+2:0] [INTPRIORITY_BITS-1:0] levelx_intpend_w_prior_en_4; -logic [TOTAL_INT+2:0] [ID_BITS-1:0] levelx_intpend_id_4; - for (m=0; m<=(TOTAL_INT)/(2**(4)) ; m++) begin : COMPARE3 - if ( m == (TOTAL_INT)/(2**(4))) begin - assign levelx_intpend_w_prior_en_4[m+1] = '0 ; - assign levelx_intpend_id_4[m+1] = '0 ; - end - cmp_and_mux #( - .ID_BITS(ID_BITS), - .INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l4 ( - .a_id(levelx_intpend_id_3[2*m]), - .a_priority(levelx_intpend_w_prior_en_3[2*m]), - .b_id(levelx_intpend_id_3[2*m+1]), - .b_priority(levelx_intpend_w_prior_en_3[2*m+1]), - .out_id(levelx_intpend_id_4[m]), - .out_priority(levelx_intpend_w_prior_en_4[m])) ; - - end - -assign claimid_in[ID_BITS-1:0] = levelx_intpend_id_4[0] ; // This is the last level output -assign selected_int_priority[INTPRIORITY_BITS-1:0] = levelx_intpend_w_prior_en_4[0] ; -`else -// LEVEL0 -logic [TOTAL_INT+2:0] [INTPRIORITY_BITS-1:0] level_intpend_w_prior_en_1; -logic [TOTAL_INT+2:0] [ID_BITS-1:0] level_intpend_id_1; - for (m=0; m<=(TOTAL_INT)/(2**(1)) ; m++) begin : COMPARE0 - if ( m == (TOTAL_INT)/(2**(1))) begin - assign level_intpend_w_prior_en_1[m+1] = '0 ; - assign level_intpend_id_1[m+1] = '0 ; - end - cmp_and_mux #( - .ID_BITS(ID_BITS), - .INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l1 ( - .a_id(level_intpend_id[0][2*m]), - .a_priority(level_intpend_w_prior_en[0][2*m]), - .b_id(level_intpend_id[0][2*m+1]), - .b_priority(level_intpend_w_prior_en[0][2*m+1]), - .out_id(level_intpend_id_1[m]), - .out_priority(level_intpend_w_prior_en_1[m])) ; - - end - -// LEVEL1 -logic [TOTAL_INT+2:0] [INTPRIORITY_BITS-1:0] level_intpend_w_prior_en_2; -logic [TOTAL_INT+2:0] [ID_BITS-1:0] level_intpend_id_2; - for (m=0; m<=(TOTAL_INT)/(2**(2)) ; m++) begin : COMPARE1 - if ( m == (TOTAL_INT)/(2**(2))) begin - assign level_intpend_w_prior_en_2[m+1] = '0 ; - assign level_intpend_id_2[m+1] = '0 ; - end - cmp_and_mux #( - .ID_BITS(ID_BITS), - .INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l2 ( - .a_id(level_intpend_id_1[2*m]), - .a_priority(level_intpend_w_prior_en_1[2*m]), - .b_id(level_intpend_id_1[2*m+1]), - .b_priority(level_intpend_w_prior_en_1[2*m+1]), - .out_id(level_intpend_id_2[m]), - .out_priority(level_intpend_w_prior_en_2[m])) ; - - end - -// LEVEL2 -logic [TOTAL_INT+2:0] [INTPRIORITY_BITS-1:0] level_intpend_w_prior_en_3; -logic [TOTAL_INT+2:0] [ID_BITS-1:0] level_intpend_id_3; - for (m=0; m<=(TOTAL_INT)/(2**(3)) ; m++) begin : COMPARE2 - if ( m == (TOTAL_INT)/(2**(3))) begin - assign level_intpend_w_prior_en_3[m+1] = '0 ; - assign level_intpend_id_3[m+1] = '0 ; - end - cmp_and_mux #( - .ID_BITS(ID_BITS), - .INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l3 ( - .a_id(level_intpend_id_2[2*m]), - .a_priority(level_intpend_w_prior_en_2[2*m]), - .b_id(level_intpend_id_2[2*m+1]), - .b_priority(level_intpend_w_prior_en_2[2*m+1]), - .out_id(level_intpend_id_3[m]), - .out_priority(level_intpend_w_prior_en_3[m])) ; - - end - -// LEVEL3 -logic [TOTAL_INT+2:0] [INTPRIORITY_BITS-1:0] level_intpend_w_prior_en_4; -logic [TOTAL_INT+2:0] [ID_BITS-1:0] level_intpend_id_4; - for (m=0; m<=(TOTAL_INT)/(2**(4)) ; m++) begin : COMPARE3 - if ( m == (TOTAL_INT)/(2**(4))) begin - assign level_intpend_w_prior_en_4[m+1] = '0 ; - assign level_intpend_id_4[m+1] = '0 ; - end - cmp_and_mux #( - .ID_BITS(ID_BITS), - .INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l4 ( - .a_id(level_intpend_id_3[2*m]), - .a_priority(level_intpend_w_prior_en_3[2*m]), - .b_id(level_intpend_id_3[2*m+1]), - .b_priority(level_intpend_w_prior_en_3[2*m+1]), - .out_id(level_intpend_id_4[m]), - .out_priority(level_intpend_w_prior_en_4[m])) ; - - end - -assign claimid_in[ID_BITS-1:0] = level_intpend_id_4[0] ; // This is the last level output -assign selected_int_priority[INTPRIORITY_BITS-1:0] = level_intpend_w_prior_en_4[0] ; -`endif diff --git a/configs/snapshots/default/pic_map_auto.h b/configs/snapshots/default/pic_map_auto.h deleted file mode 100644 index 60568b3..0000000 --- a/configs/snapshots/default/pic_map_auto.h +++ /dev/null @@ -1,31 +0,0 @@ -// mask[3:0] = { 4'b1000 - 30b mask,4'b0100 - 31b mask, 4'b0010 - 28b mask, 4'b0001 - 32b mask } -always_comb begin - case (address[14:0]) - 15'b011000000000000 : mask[3:0] = 4'b0100; - 15'b100000000000100 : mask[3:0] = 4'b1000; - 15'b100000000001000 : mask[3:0] = 4'b1000; - 15'b100000000001100 : mask[3:0] = 4'b1000; - 15'b100000000010000 : mask[3:0] = 4'b1000; - 15'b100000000010100 : mask[3:0] = 4'b1000; - 15'b100000000011000 : mask[3:0] = 4'b1000; - 15'b100000000011100 : mask[3:0] = 4'b1000; - 15'b100000000100000 : mask[3:0] = 4'b1000; - 15'b010000000000100 : mask[3:0] = 4'b0100; - 15'b010000000001000 : mask[3:0] = 4'b0100; - 15'b010000000001100 : mask[3:0] = 4'b0100; - 15'b010000000010000 : mask[3:0] = 4'b0100; - 15'b010000000010100 : mask[3:0] = 4'b0100; - 15'b010000000011000 : mask[3:0] = 4'b0100; - 15'b010000000011100 : mask[3:0] = 4'b0100; - 15'b010000000100000 : mask[3:0] = 4'b0100; - 15'b000000000000100 : mask[3:0] = 4'b0010; - 15'b000000000001000 : mask[3:0] = 4'b0010; - 15'b000000000001100 : mask[3:0] = 4'b0010; - 15'b000000000010000 : mask[3:0] = 4'b0010; - 15'b000000000010100 : mask[3:0] = 4'b0010; - 15'b000000000011000 : mask[3:0] = 4'b0010; - 15'b000000000011100 : mask[3:0] = 4'b0010; - 15'b000000000100000 : mask[3:0] = 4'b0010; - default : mask[3:0] = 4'b0001; - endcase -end diff --git a/configs/snapshots/default/whisper.json b/configs/snapshots/default/whisper.json deleted file mode 100644 index 2593f72..0000000 --- a/configs/snapshots/default/whisper.json +++ /dev/null @@ -1,395 +0,0 @@ -{ - "memmap" : { - "cosnoleio" : "0xd0580000" - }, - "nmi_vec" : "0x11110000", - "dccm" : { - "region" : "0xf", - "offset" : "0x40000", - "size" : "0x10000" - }, - "num_mmode_perf_regs" : "4", - "load_error_rollback" : "1", - "reset_vec" : "0x80000000", - "triggers" : [ - { - "poke_mask" : [ - "0x081818c7", - "0xffffffff", - "0x00000000" - ], - "reset" : [ - "0x23e00000", - "0x00000000", - "0x00000000" - ], - "mask" : [ - "0x081818c7", - "0xffffffff", - "0x00000000" - ] - }, - { - "poke_mask" : [ - "0x081818c7", - "0xffffffff", - "0x00000000" - ], - "reset" : [ - "0x23e00000", - "0x00000000", - "0x00000000" - ], - "mask" : [ - "0x081818c7", - "0xffffffff", - "0x00000000" - ] - }, - { - "poke_mask" : [ - "0x081818c7", - "0xffffffff", - "0x00000000" - ], - "reset" : [ - "0x23e00000", - "0x00000000", - "0x00000000" - ], - "mask" : [ - "0x081818c7", - "0xffffffff", - "0x00000000" - ] - }, - { - "poke_mask" : [ - "0x081818c7", - "0xffffffff", - "0x00000000" - ], - "reset" : [ - "0x23e00000", - "0x00000000", - "0x00000000" - ], - "mask" : [ - "0x081818c7", - "0xffffffff", - "0x00000000" - ] - } - ], - "xlen" : 32, - "pic" : { - "meigwctrl_offset" : "0x4000", - "region" : "0xf", - "total_int" : 8, - "size" : "0x8000", - "mpiccfg_offset" : "0x3000", - "meigwclr_offset" : "0x5000", - "total_int_plus1" : 9, - "meipt_offset" : "0x3004", - "int_words" : 1, - "meie_offset" : "0x2000", - "bits" : 15, - "meip_offset" : "0x1000", - "meipl_offset" : "0x0000", - "offset" : "0xc0000" - }, - "store_error_rollback" : "0", - "even_odd_trigger_chains" : "true", - "max_mmode_perf_event" : "50", - "csr" : { - "pmpaddr9" : { - "exists" : "false" - }, - "dicad1" : { - "reset" : "0x0", - "number" : "0x7ca", - "comment" : "Cache diagnostics.", - "debug" : "true", - "exists" : "true", - "mask" : "0x3" - }, - "pmpcfg0" : { - "exists" : "false" - }, - "mhpmcounter4h" : { - "reset" : "0x0", - "exists" : "true", - "mask" : "0xffffffff" - }, - "dicago" : { - "reset" : "0x0", - "number" : "0x7cb", - "comment" : "Cache diagnostics.", - "debug" : "true", - "exists" : "true", - "mask" : "0x0" - }, - "mie" : { - "reset" : "0x0", - "exists" : "true", - "mask" : "0x40000888" - }, - "misa" : { - "reset" : "0x40001104", - "exists" : "true", - "mask" : "0x0" - }, - "mhpmcounter6h" : { - "reset" : "0x0", - "exists" : "true", - "mask" : "0xffffffff" - }, - "meicpct" : { - "reset" : "0x0", - "number" : "0xbca", - "comment" : "External claim id/priority capture.", - "exists" : "true", - "mask" : "0x0" - }, - "mimpid" : { - "reset" : "0x1", - "exists" : "true", - "mask" : "0x0" - }, - "mcpc" : { - "reset" : "0x0", - "number" : "0x7c2", - "exists" : "true", - "mask" : "0x0" - }, - "mhpmevent4" : { - "reset" : "0x0", - "exists" : "true", - "mask" : "0xffffffff" - }, - "pmpaddr8" : { - "exists" : "false" - }, - "pmpcfg3" : { - "exists" : "false" - }, - "marchid" : { - "reset" : "0x0000000b", - "exists" : "true", - "mask" : "0x0" - }, - "pmpaddr5" : { - "exists" : "false" - }, - "mfdc" : { - "reset" : "0x00070000", - "number" : "0x7f9", - "exists" : "true", - "mask" : "0x000707ff" - }, - "mhpmevent6" : { - "reset" : "0x0", - "exists" : "true", - "mask" : "0xffffffff" - }, - "mvendorid" : { - "reset" : "0x45", - "exists" : "true", - "mask" : "0x0" - }, - "pmpaddr4" : { - "exists" : "false" - }, - "dcsr" : { - "poke_mask" : "0x00008dcc", - "reset" : "0x40000003", - "exists" : "true", - "mask" : "0x00008c04" - }, - "cycle" : { - "exists" : "false" - }, - "pmpaddr12" : { - "exists" : "false" - }, - "pmpaddr3" : { - "exists" : "false" - }, - "mhpmcounter3h" : { - "reset" : "0x0", - "exists" : "true", - "mask" : "0xffffffff" - }, - "time" : { - "exists" : "false" - }, - "meicidpl" : { - "reset" : "0x0", - "number" : "0xbcb", - "comment" : "External interrupt claim id priority level.", - "exists" : "true", - "mask" : "0xf" - }, - "pmpaddr14" : { - "exists" : "false" - }, - "pmpaddr13" : { - "exists" : "false" - }, - "pmpaddr1" : { - "exists" : "false" - }, - "mhpmcounter6" : { - "reset" : "0x0", - "exists" : "true", - "mask" : "0xffffffff" - }, - "dicad0" : { - "reset" : "0x0", - "number" : "0x7c9", - "comment" : "Cache diagnostics.", - "debug" : "true", - "exists" : "true", - "mask" : "0xffffffff" - }, - "meipt" : { - "reset" : "0x0", - "number" : "0xbc9", - "comment" : "External interrupt priority threshold.", - "exists" : "true", - "mask" : "0xf" - }, - "pmpaddr15" : { - "exists" : "false" - }, - "mhpmcounter5" : { - "reset" : "0x0", - "exists" : "true", - "mask" : "0xffffffff" - }, - "pmpcfg1" : { - "exists" : "false" - }, - "pmpaddr10" : { - "exists" : "false" - }, - "pmpaddr0" : { - "exists" : "false" - }, - "pmpcfg2" : { - "exists" : "false" - }, - "pmpaddr2" : { - "exists" : "false" - }, - "mpmc" : { - "reset" : "0x0", - "number" : "0x7c6", - "comment" : "Core pause: Implemented as read only.", - "exists" : "true", - "mask" : "0x0" - }, - "dmst" : { - "reset" : "0x0", - "number" : "0x7c4", - "comment" : "Memory synch trigger: Flush caches in debug mode.", - "debug" : "true", - "exists" : "true", - "mask" : "0x0" - }, - "instret" : { - "exists" : "false" - }, - "mhpmevent3" : { - "reset" : "0x0", - "exists" : "true", - "mask" : "0xffffffff" - }, - "dicawics" : { - "reset" : "0x0", - "number" : "0x7c8", - "comment" : "Cache diagnostics.", - "debug" : "true", - "exists" : "true", - "mask" : "0x0130fffc" - }, - "mip" : { - "poke_mask" : "0x40000888", - "reset" : "0x0", - "exists" : "true", - "mask" : "0x0" - }, - "mhpmcounter5h" : { - "reset" : "0x0", - "exists" : "true", - "mask" : "0xffffffff" - }, - "micect" : { - "reset" : "0x0", - "number" : "0x7f0", - "exists" : "true", - "mask" : "0xffffffff" - }, - "miccmect" : { - "reset" : "0x0", - "number" : "0x7f1", - "exists" : "true", - "mask" : "0xffffffff" - }, - "mhpmevent5" : { - "reset" : "0x0", - "exists" : "true", - "mask" : "0xffffffff" - }, - "mhpmcounter3" : { - "reset" : "0x0", - "exists" : "true", - "mask" : "0xffffffff" - }, - "pmpaddr6" : { - "exists" : "false" - }, - "pmpaddr11" : { - "exists" : "false" - }, - "mcgc" : { - "poke_mask" : "0x000001ff", - "reset" : "0x0", - "number" : "0x7f8", - "exists" : "true", - "mask" : "0x000001ff" - }, - "mhpmcounter4" : { - "reset" : "0x0", - "exists" : "true", - "mask" : "0xffffffff" - }, - "mdccmect" : { - "reset" : "0x0", - "number" : "0x7f2", - "exists" : "true", - "mask" : "0xffffffff" - }, - "pmpaddr7" : { - "exists" : "false" - }, - "meicurpl" : { - "reset" : "0x0", - "number" : "0xbcc", - "comment" : "External interrupt current priority level.", - "exists" : "true", - "mask" : "0xf" - }, - "mstatus" : { - "reset" : "0x1800", - "exists" : "true", - "mask" : "0x88" - }, - "tselect" : { - "reset" : "0x0", - "exists" : "true", - "mask" : "0x3" - } - }, - "harts" : 1 -} diff --git a/design/flist.questa b/design/flist.questa new file mode 100644 index 0000000..afbd089 --- /dev/null +++ b/design/flist.questa @@ -0,0 +1,52 @@ +$RV_ROOT/workspace/work/snapshots/default/common_defines.vh +$RV_ROOT/design/include/def.sv ++incdir+$RV_ROOT/workspace/work/snapshots/default ++incdir+$RV_ROOT/design/lib ++incdir+$RV_ROOT/design/include ++incdir+$RV_ROOT/design/dmi +$RV_ROOT/design/swerv_wrapper.sv +$RV_ROOT/design/mem.sv +$RV_ROOT/design/pic_ctrl.sv +$RV_ROOT/design/swerv.sv +$RV_ROOT/design/dma_ctrl.sv +$RV_ROOT/design/ifu/ifu_aln_ctl.sv +$RV_ROOT/design/ifu/ifu_compress_ctl.sv +$RV_ROOT/design/ifu/ifu_ifc_ctl.sv +$RV_ROOT/design/ifu/ifu_bp_ctl.sv +$RV_ROOT/design/ifu/ifu_ic_mem.sv +$RV_ROOT/design/ifu/ifu_mem_ctl.sv +$RV_ROOT/design/ifu/ifu_iccm_mem.sv +$RV_ROOT/design/ifu/ifu.sv +$RV_ROOT/design/dec/dec_decode_ctl.sv +$RV_ROOT/design/dec/dec_gpr_ctl.sv +$RV_ROOT/design/dec/dec_ib_ctl.sv +$RV_ROOT/design/dec/dec_tlu_ctl.sv +$RV_ROOT/design/dec/dec_trigger.sv +$RV_ROOT/design/dec/dec.sv +$RV_ROOT/design/exu/exu_alu_ctl.sv +$RV_ROOT/design/exu/exu_mul_ctl.sv +$RV_ROOT/design/exu/exu_div_ctl.sv +$RV_ROOT/design/exu/exu.sv +$RV_ROOT/design/lsu/lsu.sv +$RV_ROOT/design/lsu/lsu_clkdomain.sv +$RV_ROOT/design/lsu/lsu_addrcheck.sv +$RV_ROOT/design/lsu/lsu_lsc_ctl.sv +$RV_ROOT/design/lsu/lsu_stbuf.sv +$RV_ROOT/design/lsu/lsu_bus_buffer.sv +$RV_ROOT/design/lsu/lsu_bus_intf.sv +$RV_ROOT/design/lsu/lsu_ecc.sv +$RV_ROOT/design/lsu/lsu_dccm_mem.sv +$RV_ROOT/design/lsu/lsu_dccm_ctl.sv +$RV_ROOT/design/lsu/lsu_trigger.sv +$RV_ROOT/design/dbg/dbg.sv +$RV_ROOT/design/dmi/dmi_wrapper.v +$RV_ROOT/design/dmi/dmi_jtag_to_core_sync.v +$RV_ROOT/design/dmi/rvjtag_tap.sv +$RV_ROOT/design/lib/beh_lib.sv +$RV_ROOT/design/lib/mem_lib.sv +$RV_ROOT/design/lib/svci_to_ahb.sv +$RV_ROOT/design/lib/ahb_to_svci.sv +$RV_ROOT/design/lib/svci_to_axi4.sv +$RV_ROOT/design/lib/axi4_to_svci.sv +$RV_ROOT/design/lib/ahb_to_axi4.sv +$RV_ROOT/design/lib/axi4_to_ahb.sv diff --git a/design/lib/svci_to_axi4.sv b/design/lib/svci_to_axi4.sv new file mode 100644 index 0000000..20c6a8e --- /dev/null +++ b/design/lib/svci_to_axi4.sv @@ -0,0 +1,208 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2018 Western Digital Corporation or it's affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//******************************************************************************** +// $Id$ +// +// Owner: +// Function: SVCI to AXI4 Bridge +// Comments: +// +//******************************************************************************** +module svci_to_axi4 #(parameter TAG = 1, + ID = 1, + PRTY = 1) ( + + input logic clk, + input logic rst_l, + input logic scan_mode, + input logic bus_clk_en, + input logic clk_override, + + // AXI signals + // AXI Write Channels + output logic axi_awvalid, + input logic axi_awready, + output logic axi_awposted, + output logic [TAG-1:0] axi_awid, + output logic [31:0] axi_awaddr, + output logic [2:0] axi_awsize, + output logic [2:0] axi_awprot, + output logic [7:0] axi_awlen, + output logic [1:0] axi_awburst, + output logic [ID-1:0] axi_awmid, + output logic [PRTY-1:0] axi_awprty, + + output logic axi_wvalid, + input logic axi_wready, + output logic [63:0] axi_wdata, + output logic [7:0] axi_wstrb, + output logic axi_wlast, + + input logic axi_bvalid, + output logic axi_bready, + input logic axi_bposted, + input logic [1:0] axi_bresp, + input logic [TAG-1:0] axi_bid, + input logic [ID-1:0] axi_bmid, + input logic [PRTY-1:0] axi_bprty, + + // AXI Read Channels + output logic axi_arvalid, + input logic axi_arready, + output logic [TAG-1:0] axi_arid, + output logic [31:0] axi_araddr, + output logic [2:0] axi_arsize, + output logic [2:0] axi_arprot, + output logic [7:0] axi_arlen, + output logic [1:0] axi_arburst, + output logic [ID-1:0] axi_armid, + output logic [PRTY-1:0] axi_arprty, + + input logic axi_rvalid, + output logic axi_rready, + input logic [TAG-1:0] axi_rid, + input logic [63:0] axi_rdata, + input logic [1:0] axi_rresp, + input logic [ID-1:0] axi_rmid, + input logic [PRTY-1:0] axi_rprty, + + // SVCI signals + input logic svci_cmd_valid, + output logic svci_cmd_ready, + input logic [TAG-1:0] svci_cmd_tag, + input logic [ID-1:0] svci_cmd_mid, + input logic [31:0] svci_cmd_addr, + input logic [63:0] svci_cmd_wdata, + input logic [7:0] svci_cmd_wbe, + input logic [2:0] svci_cmd_length, + input logic [2:0] svci_cmd_opc, + input logic [PRTY-1:0] svci_cmd_prty, + input logic dma_slv_algn_err, + + output logic svci_rsp_valid, + input logic svci_rsp_ready, + output logic [TAG-1:0] svci_rsp_tag, + output logic [ID-1:0] svci_rsp_mid, + output logic [63:0] svci_rsp_rdata, + output logic [3:0] svci_rsp_opc, + output logic [PRTY-1:0] svci_rsp_prty +); + + logic cmdbuf_wr_en, cmdbuf_data_en, cmdbuf_rst, cmdbuf_data_rst; + logic cmdbuf_full; + logic cmdbuf_vld, cmdbuf_data_vld; + logic [2:0] cmdbuf_opc, cmdbuf_size; + logic [7:0] cmdbuf_wstrb; + logic [31:0] cmdbuf_addr; + logic [63:0] cmdbuf_wdata; + logic [TAG-1:0] cmdbuf_tag; + logic [ID-1:0] cmdbuf_mid; + logic [PRTY-1:0] cmdbuf_prty; + + logic wrbuf_en, wrbuf_rst; + logic wrbuf_vld; + logic wrbuf_posted; + logic [TAG-1:0] wrbuf_tag; + logic [ID-1:0] wrbuf_mid; + logic [1:0] wrbuf_resp; + logic [63:0] error_address; // SVCI needs the error address back on the rdata. + logic [PRTY-1:0] wrbuf_prty; + + logic [1:0] axi_bresp_in; // need to map 2 errors in to 3 errors + logic bus_clk; + + // Command buffer + assign cmdbuf_wr_en = svci_cmd_valid & svci_cmd_ready; + assign cmdbuf_data_en = cmdbuf_wr_en & (svci_cmd_opc[2:1] == 2'b01); + assign cmdbuf_rst = ((axi_awvalid & axi_awready) | (axi_arvalid & axi_arready)) & ~cmdbuf_wr_en; + assign cmdbuf_data_rst = (axi_wvalid & axi_wready) & (cmdbuf_opc[2:1] == 2'b01) & ~cmdbuf_data_en; + + assign cmdbuf_full = (cmdbuf_vld & ~((axi_awvalid & axi_awready) | (axi_arvalid & axi_arready))) | (cmdbuf_data_vld & ~((axi_wvalid & axi_wready) & (cmdbuf_opc[2:1] == 2'b01))); + + rvdffsc #(.WIDTH(1)) cmdbuf_vldff(.din(1'b1), .dout(cmdbuf_vld), .en(cmdbuf_wr_en), .clear(cmdbuf_rst), .clk(bus_clk), .*); + rvdffsc #(.WIDTH(1)) cmdbuf_data_vldff(.din(1'b1), .dout(cmdbuf_data_vld), .en(cmdbuf_data_en), .clear(cmdbuf_data_rst), .clk(bus_clk), .*); + rvdffs #(.WIDTH(3)) cmdbuf_opcff(.din(svci_cmd_opc[2:0]), .dout(cmdbuf_opc[2:0]), .en(cmdbuf_wr_en), .clk(bus_clk), .*); + rvdffs #(.WIDTH(3)) cmdbuf_sizeff(.din(svci_cmd_length[2:0]), .dout(cmdbuf_size[2:0]), .en(cmdbuf_wr_en), .clk(bus_clk), .*); + rvdffe #(.WIDTH(8)) cmdbuf_wstrbff(.din(svci_cmd_wbe[7:0]), .dout(cmdbuf_wstrb[7:0]), .en(cmdbuf_wr_en & bus_clk_en), .*); + rvdffe #(.WIDTH(32)) cmdbuf_addrff(.din(svci_cmd_addr[31:0]), .dout(cmdbuf_addr[31:0]), .en(cmdbuf_wr_en & bus_clk_en), .*); + rvdffe #(.WIDTH(64)) cmdbuf_wdataff(.din(svci_cmd_wdata[63:0]), .dout(cmdbuf_wdata[63:0]), .en(cmdbuf_data_en & bus_clk_en), .*); + rvdffs #(.WIDTH(TAG)) cmdbuf_tagff(.din(svci_cmd_tag[TAG-1:0]), .dout(cmdbuf_tag[TAG-1:0]), .en(cmdbuf_wr_en), .clk(bus_clk), .*); + rvdffs #(.WIDTH(ID)) cmdbuf_midff(.din(svci_cmd_mid[ID-1:0]), .dout(cmdbuf_mid[ID-1:0]), .en(cmdbuf_wr_en), .clk(bus_clk), .*); + rvdffs #(.WIDTH(PRTY)) cmdbuf_prtyff(.din(svci_cmd_prty[PRTY-1:0]), .dout(cmdbuf_prty[PRTY-1:0]), .en(cmdbuf_wr_en), .clk(bus_clk), .*); + + // AXI Write Channels + assign axi_awvalid = cmdbuf_vld & (cmdbuf_opc[2:1] == 2'b01); + assign axi_awposted = axi_awvalid & ~cmdbuf_opc[0]; + assign axi_awid[TAG-1:0] = cmdbuf_tag[TAG-1:0]; + assign axi_awaddr[31:0] = cmdbuf_addr[31:0]; + assign axi_awsize[2:0] = cmdbuf_size[2:0]; + assign axi_awprot[2:0] = 3'b0; + assign axi_awlen[7:0] = '0; + assign axi_awburst[1:0] = 2'b01; + assign axi_awmid = cmdbuf_mid[ID-1:0]; + assign axi_awprty = cmdbuf_prty[PRTY-1:0]; + + assign axi_wvalid = cmdbuf_data_vld; + assign axi_wdata[63:0] = cmdbuf_wdata[63:0]; + assign axi_wstrb[7:0] = cmdbuf_wstrb[7:0]; + assign axi_wlast = 1'b1; + + assign axi_bready = ~wrbuf_vld | svci_rsp_ready; + + // AXI Read Channels + assign axi_arvalid = cmdbuf_vld & (cmdbuf_opc[2:0] == 3'b0); + assign axi_arid[TAG-1:0] = cmdbuf_tag[TAG-1:0]; + assign axi_araddr[31:0] = cmdbuf_addr[31:0]; + assign axi_arsize[2:0] = cmdbuf_size[2:0]; + assign axi_arprot = 3'b0; + assign axi_arlen[7:0] = '0; + assign axi_arburst[1:0] = 2'b01; + assign axi_armid = cmdbuf_mid[ID-1:0]; + assign axi_rready = ~wrbuf_vld & svci_rsp_ready; + assign axi_arprty = cmdbuf_prty[PRTY-1:0]; + + // SVCI_response signals + assign svci_rsp_valid = wrbuf_vld | axi_rvalid; + assign svci_rsp_tag[TAG-1:0] = wrbuf_vld ? wrbuf_tag[TAG-1:0] : axi_rid[TAG-1:0]; + assign svci_rsp_mid[ID-1:0] = wrbuf_vld ? wrbuf_mid[ID-1:0] : axi_rmid[ID-1:0]; + assign svci_rsp_rdata[63:0] = wrbuf_vld ? {32'b0, error_address[31:0]} : axi_rdata[63:0]; // rdata + assign svci_rsp_opc[3:2] = wrbuf_vld ? {1'b1, ~wrbuf_posted} : 2'b0; + // assign svci_rsp_opc[1:0] = wrbuf_vld ? {wrbuf_resp[1] ? (wrbuf_resp[0] ? 2'b10 : 2'b01) : 2'b0} : // AXI Slave Error -> SVCI Slave Error, AXI Decode Error -> SVCI Address Error + // {axi_rresp[1] ? (axi_rresp[0] ? 2'b10 : 2'b01) : 2'b0}; + assign svci_rsp_opc[1:0] = wrbuf_vld ? wrbuf_resp[1:0] : // AXI Slave Error -> SVCI Slave Error, AXI Decode Error -> SVCI Address Error + {axi_rresp[1] ? (axi_rresp[0] ? 2'b10 : {dma_slv_algn_err, 1'b1}) : 2'b0}; + assign svci_rsp_prty[PRTY-1:0] = wrbuf_vld ? wrbuf_prty[PRTY-1:0] : axi_rprty[PRTY-1:0]; + + assign svci_cmd_ready = ~cmdbuf_full; + + // Write Response Buffer. Errors for writes need to send the Error address back on the rsp_rdata for SVCI. The address is sent back on axi_rdata bus for both reads and writes that have errors. + // assign wrbuf_en = axi_bvalid & svci_rsp_ready & (~axi_bposted | axi_bresp[1]); + assign wrbuf_en = axi_bvalid & axi_bready & (~axi_bposted | axi_bresp[1]); + assign wrbuf_rst = svci_rsp_valid & svci_rsp_ready & svci_rsp_opc[3] & ~wrbuf_en; + assign axi_bresp_in[1:0] = {axi_bresp[1] ? (axi_bresp[0] ? 2'b10 : {dma_slv_algn_err, 1'b1}) : 2'b0}; + rvdffsc #(.WIDTH(1)) wrbuf_vldff (.din(1'b1), .dout(wrbuf_vld), .en(wrbuf_en), .clear(wrbuf_rst), .clk(bus_clk), .*); + rvdffs #(.WIDTH(32)) wrbuf_erroff (.din(axi_rdata[31:0]), .dout(error_address[31:0]), .en(wrbuf_en), .clk(bus_clk), .*); + rvdffs #(.WIDTH(1)) wrbuf_postedff(.din(axi_bposted), .dout(wrbuf_posted), .en(wrbuf_en), .clk(bus_clk), .*); + rvdffs #(.WIDTH(TAG)) wrbuf_tagff (.din(axi_bid[TAG-1:0]), .dout(wrbuf_tag[TAG-1:0]), .en(wrbuf_en), .clk(bus_clk), .*); + rvdffs #(.WIDTH(ID)) wrbuf_midff (.din(axi_bmid[ID-1:0]), .dout(wrbuf_mid[ID-1:0]), .en(wrbuf_en), .clk(bus_clk), .*); + rvdffs #(.WIDTH(PRTY))wrbuf_prtyff (.din(axi_bprty[PRTY-1:0]), .dout(wrbuf_prty[PRTY-1:0]), .en(wrbuf_en), .clk(bus_clk), .*); + rvdffs #(.WIDTH(2)) wrbuf_respff (.din(axi_bresp_in[1:0]), .dout(wrbuf_resp[1:0]), .en(wrbuf_en), .clk(bus_clk), .*); + + // Clock header logic + rvclkhdr bus_cgc (.en(bus_clk_en), .l1clk(bus_clk), .*); + +endmodule // svci_to_axi4 + diff --git a/docs/RISC-V SweRV EH1 PRM.pdf b/docs/RISC-V SweRV EH1 PRM.pdf deleted file mode 100644 index a11fd16..0000000 Binary files a/docs/RISC-V SweRV EH1 PRM.pdf and /dev/null differ diff --git a/docs/RISC-V_SweRV_EH1_PRM.pdf b/docs/RISC-V_SweRV_EH1_PRM.pdf new file mode 100755 index 0000000..1a20363 Binary files /dev/null and b/docs/RISC-V_SweRV_EH1_PRM.pdf differ diff --git a/testbench/asm/cmark.c b/testbench/asm/cmark.c new file mode 100644 index 0000000..4e7a9b7 --- /dev/null +++ b/testbench/asm/cmark.c @@ -0,0 +1,2403 @@ +#include "defines.h" + +#define ITERATIONS 1 +extern int STACK; +void main(); + + +#define STDOUT 0xd0580000 + +__asm (".section .text"); +__asm (".global _start"); +__asm ("_start:"); + +// Enable Caches in MRAC +__asm ("li t0, 0x5f555555"); +__asm ("csrw 0x7c0, t0"); + +// Set stack pointer. +__asm ("la sp, STACK"); + +__asm ("jal main"); + +// Write 0xff to STDOUT for TB to termiate test. +__asm (".global _finish"); +__asm ("_finish:"); +__asm ("li t0, 0xd0580000"); +__asm ("addi t1, zero, 0xff"); +__asm ("sb t1, 0(t0)"); +__asm ("beq x0, x0, _finish"); +__asm (".rept 10"); +__asm ("nop"); +__asm (".endr"); + + +/* +Author : Shay Gal-On, EEMBC + +This file is part of EEMBC(R) and CoreMark(TM), which are Copyright (C) 2009 +All rights reserved. + +EEMBC CoreMark Software is a product of EEMBC and is provided under the terms of the +CoreMark License that is distributed with the official EEMBC COREMARK Software release. +If you received this EEMBC CoreMark Software without the accompanying CoreMark License, +you must discontinue use and download the official release from www.coremark.org. + +Also, if you are publicly displaying scores generated from the EEMBC CoreMark software, +make sure that you are in compliance with Run and Reporting rules specified in the accompanying readme.txt file. + +EEMBC +4354 Town Center Blvd. Suite 114-200 +El Dorado Hills, CA, 95762 +*/ + +//#include "/wd/users/jrahmeh/coremark_v1.0/riscv/coremark.h" + +/* +Author : Shay Gal-On, EEMBC + +This file is part of EEMBC(R) and CoreMark(TM), which are Copyright (C) 2009 +All rights reserved. + +EEMBC CoreMark Software is a product of EEMBC and is provided under the terms of the +CoreMark License that is distributed with the official EEMBC COREMARK Software release. +If you received this EEMBC CoreMark Software without the accompanying CoreMark License, +you must discontinue use and download the official release from www.coremark.org. + +Also, if you are publicly displaying scores generated from the EEMBC CoreMark software, +make sure that you are in compliance with Run and Reporting rules specified in the accompanying readme.txt file. + +EEMBC +4354 Town Center Blvd. Suite 114-200 +El Dorado Hills, CA, 95762 +*/ +/* Topic: Description + This file contains declarations of the various benchmark functions. +*/ + +/* Configuration: TOTAL_DATA_SIZE + Define total size for data algorithms will operate on +*/ +#ifndef TOTAL_DATA_SIZE +#define TOTAL_DATA_SIZE 2*1000 +#endif + +#define SEED_ARG 0 +#define SEED_FUNC 1 +#define SEED_VOLATILE 2 + +#define MEM_STATIC 0 +#define MEM_MALLOC 1 +#define MEM_STACK 2 + +/* File : core_portme.h */ + +/* + Author : Shay Gal-On, EEMBC + Legal : TODO! +*/ +/* Topic : Description + This file contains configuration constants required to execute on different platforms +*/ +#ifndef CORE_PORTME_H +#define CORE_PORTME_H +/************************/ +/* Data types and settings */ +/************************/ +/* Configuration : HAS_FLOAT + Define to 1 if the platform supports floating point. +*/ +#ifndef HAS_FLOAT +#define HAS_FLOAT 0 +#endif +/* Configuration : HAS_TIME_H + Define to 1 if platform has the time.h header file, + and implementation of functions thereof. +*/ +#ifndef HAS_TIME_H +#define HAS_TIME_H 0 +#endif +/* Configuration : USE_CLOCK + Define to 1 if platform has the time.h header file, + and implementation of functions thereof. +*/ +#ifndef USE_CLOCK +#define USE_CLOCK 0 +#endif +/* Configuration : HAS_STDIO + Define to 1 if the platform has stdio.h. +*/ +#ifndef HAS_STDIO +#define HAS_STDIO 0 +#endif +/* Configuration : HAS_PRINTF + Define to 1 if the platform has stdio.h and implements the printf function. +*/ +#ifndef HAS_PRINTF +#define HAS_PRINTF 1 +int whisperPrintf(const char* format, ...); +#define ee_printf whisperPrintf +#endif + +/* Configuration : CORE_TICKS + Define type of return from the timing functions. + */ +#include +typedef clock_t CORE_TICKS; + +/* Definitions : COMPILER_VERSION, COMPILER_FLAGS, MEM_LOCATION + Initialize these strings per platform +*/ +#ifndef COMPILER_VERSION + #ifdef __GNUC__ + #define COMPILER_VERSION "GCC"__VERSION__ + #else + #define COMPILER_VERSION "Please put compiler version here (e.g. gcc 4.1)" + #endif +#endif +#ifndef COMPILER_FLAGS + #define COMPILER_FLAGS "-O2" +#endif + +#ifndef MEM_LOCATION +// #define MEM_LOCATION "STACK" + #define MEM_LOCATION "STATIC" +#endif + +/* Data Types : + To avoid compiler issues, define the data types that need ot be used for 8b, 16b and 32b in . + + *Imprtant* : + ee_ptr_int needs to be the data type used to hold pointers, otherwise coremark may fail!!! +*/ +typedef signed short ee_s16; +typedef unsigned short ee_u16; +typedef signed int ee_s32; +typedef double ee_f32; +typedef unsigned char ee_u8; +typedef unsigned int ee_u32; +typedef ee_u32 ee_ptr_int; +typedef size_t ee_size_t; +/* align_mem : + This macro is used to align an offset to point to a 32b value. It is used in the Matrix algorithm to initialize the input memory blocks. +*/ +#define align_mem(x) (void *)(4 + (((ee_ptr_int)(x) - 1) & ~3)) + +/* Configuration : SEED_METHOD + Defines method to get seed values that cannot be computed at compile time. + + Valid values : + SEED_ARG - from command line. + SEED_FUNC - from a system function. + SEED_VOLATILE - from volatile variables. +*/ +#ifndef SEED_METHOD +#define SEED_METHOD SEED_VOLATILE +#endif + +/* Configuration : MEM_METHOD + Defines method to get a block of memry. + + Valid values : + MEM_MALLOC - for platforms that implement malloc and have malloc.h. + MEM_STATIC - to use a static memory array. + MEM_STACK - to allocate the data block on the stack (NYI). +*/ +#ifndef MEM_METHOD +//#define MEM_METHOD MEM_STACK +#define MEM_METHOD MEM_STATIC +#endif + +/* Configuration : MULTITHREAD + Define for parallel execution + + Valid values : + 1 - only one context (default). + N>1 - will execute N copies in parallel. + + Note : + If this flag is defined to more then 1, an implementation for launching parallel contexts must be defined. + + Two sample implementations are provided. Use or to enable them. + + It is valid to have a different implementation of and in , + to fit a particular architecture. +*/ +#ifndef MULTITHREAD +#define MULTITHREAD 1 +#define USE_PTHREAD 0 +#define USE_FORK 0 +#define USE_SOCKET 0 +#endif + +/* Configuration : MAIN_HAS_NOARGC + Needed if platform does not support getting arguments to main. + + Valid values : + 0 - argc/argv to main is supported + 1 - argc/argv to main is not supported + + Note : + This flag only matters if MULTITHREAD has been defined to a value greater then 1. +*/ +#ifndef MAIN_HAS_NOARGC +#define MAIN_HAS_NOARGC 1 +#endif + +/* Configuration : MAIN_HAS_NORETURN + Needed if platform does not support returning a value from main. + + Valid values : + 0 - main returns an int, and return value will be 0. + 1 - platform does not support returning a value from main +*/ +#ifndef MAIN_HAS_NORETURN +#define MAIN_HAS_NORETURN 1 +#endif + +/* Variable : default_num_contexts + Not used for this simple port, must cintain the value 1. +*/ +extern ee_u32 default_num_contexts; + +typedef struct CORE_PORTABLE_S { + ee_u8 portable_id; +} core_portable; + +/* target specific init/fini */ +void portable_init(core_portable *p, int *argc, char *argv[]); +void portable_fini(core_portable *p); + +#if !defined(PROFILE_RUN) && !defined(PERFORMANCE_RUN) && !defined(VALIDATION_RUN) +#if (TOTAL_DATA_SIZE==1200) +#define PROFILE_RUN 1 +#elif (TOTAL_DATA_SIZE==2000) +#define PERFORMANCE_RUN 1 +#else +#define VALIDATION_RUN 1 +#endif +#endif + +#endif /* CORE_PORTME_H */ + + +#if HAS_STDIO +#include +#endif +#if HAS_PRINTF +#ifndef ee_printf +#define ee_printf printf +#endif +#endif + +/* Actual benchmark execution in iterate */ +void *iterate(void *pres); + +/* Typedef: secs_ret + For machines that have floating point support, get number of seconds as a double. + Otherwise an unsigned int. +*/ +#if HAS_FLOAT +typedef double secs_ret; +#else +typedef ee_u32 secs_ret; +#endif + +#if MAIN_HAS_NORETURN +#define MAIN_RETURN_VAL +#define MAIN_RETURN_TYPE void +#else +#define MAIN_RETURN_VAL 0 +#define MAIN_RETURN_TYPE int +#endif + +void start_time(void); +void stop_time(void); +CORE_TICKS get_time(void); +secs_ret time_in_secs(CORE_TICKS ticks); + +/* Misc useful functions */ +ee_u16 crcu8(ee_u8 data, ee_u16 crc); +ee_u16 crc16(ee_s16 newval, ee_u16 crc); +ee_u16 crcu16(ee_u16 newval, ee_u16 crc); +ee_u16 crcu32(ee_u32 newval, ee_u16 crc); +ee_u8 check_data_types(); +void *portable_malloc(ee_size_t size); +void portable_free(void *p); +ee_s32 parseval(char *valstring); + +/* Algorithm IDS */ +#define ID_LIST (1<<0) +#define ID_MATRIX (1<<1) +#define ID_STATE (1<<2) +#define ALL_ALGORITHMS_MASK (ID_LIST|ID_MATRIX|ID_STATE) +#define NUM_ALGORITHMS 3 + +/* list data structures */ +typedef struct list_data_s { + ee_s16 data16; + ee_s16 idx; +} list_data; + +typedef struct list_head_s { + struct list_head_s *next; + struct list_data_s *info; +} list_head; + + +/*matrix benchmark related stuff */ +#define MATDAT_INT 1 +#if MATDAT_INT +typedef ee_s16 MATDAT; +typedef ee_s32 MATRES; +#else +typedef ee_f16 MATDAT; +typedef ee_f32 MATRES; +#endif + +typedef struct MAT_PARAMS_S { + int N; + MATDAT *A; + MATDAT *B; + MATRES *C; +} mat_params; + +/* state machine related stuff */ +/* List of all the possible states for the FSM */ +typedef enum CORE_STATE { + CORE_START=0, + CORE_INVALID, + CORE_S1, + CORE_S2, + CORE_INT, + CORE_FLOAT, + CORE_EXPONENT, + CORE_SCIENTIFIC, + NUM_CORE_STATES +} core_state_e ; + + +/* Helper structure to hold results */ +typedef struct RESULTS_S { + /* inputs */ + ee_s16 seed1; /* Initializing seed */ + ee_s16 seed2; /* Initializing seed */ + ee_s16 seed3; /* Initializing seed */ + void *memblock[4]; /* Pointer to safe memory location */ + ee_u32 size; /* Size of the data */ + ee_u32 iterations; /* Number of iterations to execute */ + ee_u32 execs; /* Bitmask of operations to execute */ + struct list_head_s *list; + mat_params mat; + /* outputs */ + ee_u16 crc; + ee_u16 crclist; + ee_u16 crcmatrix; + ee_u16 crcstate; + ee_s16 err; + /* ultithread specific */ + core_portable port; +} core_results; + +/* Multicore execution handling */ +#if (MULTITHREAD>1) +ee_u8 core_start_parallel(core_results *res); +ee_u8 core_stop_parallel(core_results *res); +#endif + +/* list benchmark functions */ +list_head *core_list_init(ee_u32 blksize, list_head *memblock, ee_s16 seed); +ee_u16 core_bench_list(core_results *res, ee_s16 finder_idx); + +/* state benchmark functions */ +void core_init_state(ee_u32 size, ee_s16 seed, ee_u8 *p); +ee_u16 core_bench_state(ee_u32 blksize, ee_u8 *memblock, + ee_s16 seed1, ee_s16 seed2, ee_s16 step, ee_u16 crc); + +/* matrix benchmark functions */ +ee_u32 core_init_matrix(ee_u32 blksize, void *memblk, ee_s32 seed, mat_params *p); +ee_u16 core_bench_matrix(mat_params *p, ee_s16 seed, ee_u16 crc); + + + + + +/* +Topic: Description + Benchmark using a linked list. + + Linked list is a common data structure used in many applications. + + For our purposes, this will excercise the memory units of the processor. + In particular, usage of the list pointers to find and alter data. + + We are not using Malloc since some platforms do not support this library. + + Instead, the memory block being passed in is used to create a list, + and the benchmark takes care not to add more items then can be + accomodated by the memory block. The porting layer will make sure + that we have a valid memory block. + + All operations are done in place, without using any extra memory. + + The list itself contains list pointers and pointers to data items. + Data items contain the following: + + idx - An index that captures the initial order of the list. + data - Variable data initialized based on the input parameters. The 16b are divided as follows: + o Upper 8b are backup of original data. + o Bit 7 indicates if the lower 7 bits are to be used as is or calculated. + o Bits 0-2 indicate type of operation to perform to get a 7b value. + o Bits 3-6 provide input for the operation. + +*/ + +/* local functions */ + +list_head *core_list_find(list_head *list,list_data *info); +list_head *core_list_reverse(list_head *list); +list_head *core_list_remove(list_head *item); +list_head *core_list_undo_remove(list_head *item_removed, list_head *item_modified); +list_head *core_list_insert_new(list_head *insert_point + , list_data *info, list_head **memblock, list_data **datablock + , list_head *memblock_end, list_data *datablock_end); +typedef ee_s32(*list_cmp)(list_data *a, list_data *b, core_results *res); +list_head *core_list_mergesort(list_head *list, list_cmp cmp, core_results *res); + +ee_s16 calc_func(ee_s16 *pdata, core_results *res) { + ee_s16 data=*pdata; + ee_s16 retval; + ee_u8 optype=(data>>7) & 1; /* bit 7 indicates if the function result has been cached */ + if (optype) /* if cached, use cache */ + return (data & 0x007f); + else { /* otherwise calculate and cache the result */ + ee_s16 flag=data & 0x7; /* bits 0-2 is type of function to perform */ + ee_s16 dtype=((data>>3) & 0xf); /* bits 3-6 is specific data for the operation */ + dtype |= dtype << 4; /* replicate the lower 4 bits to get an 8b value */ + switch (flag) { + case 0: + if (dtype<0x22) /* set min period for bit corruption */ + dtype=0x22; + retval=core_bench_state(res->size,res->memblock[3],res->seed1,res->seed2,dtype,res->crc); + if (res->crcstate==0) + res->crcstate=retval; + break; + case 1: + retval=core_bench_matrix(&(res->mat),dtype,res->crc); + if (res->crcmatrix==0) + res->crcmatrix=retval; + break; + default: + retval=data; + break; + } + res->crc=crcu16(retval,res->crc); + retval &= 0x007f; + *pdata = (data & 0xff00) | 0x0080 | retval; /* cache the result */ + return retval; + } +} +/* Function: cmp_complex + Compare the data item in a list cell. + + Can be used by mergesort. +*/ +ee_s32 cmp_complex(list_data *a, list_data *b, core_results *res) { + ee_s16 val1=calc_func(&(a->data16),res); + ee_s16 val2=calc_func(&(b->data16),res); + return val1 - val2; +} + +/* Function: cmp_idx + Compare the idx item in a list cell, and regen the data. + + Can be used by mergesort. +*/ +ee_s32 cmp_idx(list_data *a, list_data *b, core_results *res) { + if (res==NULL) { + a->data16 = (a->data16 & 0xff00) | (0x00ff & (a->data16>>8)); + b->data16 = (b->data16 & 0xff00) | (0x00ff & (b->data16>>8)); + } + return a->idx - b->idx; +} + +void copy_info(list_data *to,list_data *from) { + to->data16=from->data16; + to->idx=from->idx; +} + +/* Benchmark for linked list: + - Try to find multiple data items. + - List sort + - Operate on data from list (crc) + - Single remove/reinsert + * At the end of this function, the list is back to original state +*/ +ee_u16 core_bench_list(core_results *res, ee_s16 finder_idx) { + ee_u16 retval=0; + ee_u16 found=0,missed=0; + list_head *list=res->list; + ee_s16 find_num=res->seed3; + list_head *this_find; + list_head *finder, *remover; + list_data info; + ee_s16 i; + + info.idx=finder_idx; + /* find values in the list, and change the list each time (reverse and cache if value found) */ + for (i=0; inext->info->data16 >> 8) & 1; + } + else { + found++; + if (this_find->info->data16 & 0x1) /* use found value */ + retval+=(this_find->info->data16 >> 9) & 1; + /* and cache next item at the head of the list (if any) */ + if (this_find->next != NULL) { + finder = this_find->next; + this_find->next = finder->next; + finder->next=list->next; + list->next=finder; + } + } + if (info.idx>=0) + info.idx++; +#if CORE_DEBUG + ee_printf("List find %d: [%d,%d,%d]\n",i,retval,missed,found); +#endif + } + retval+=found*4-missed; + /* sort the list by data content and remove one item*/ + if (finder_idx>0) + list=core_list_mergesort(list,cmp_complex,res); + remover=core_list_remove(list->next); + /* CRC data content of list from location of index N forward, and then undo remove */ + finder=core_list_find(list,&info); + if (!finder) + finder=list->next; + while (finder) { + retval=crc16(list->info->data16,retval); + finder=finder->next; + } +#if CORE_DEBUG + ee_printf("List sort 1: %04x\n",retval); +#endif + remover=core_list_undo_remove(remover,list->next); + /* sort the list by index, in effect returning the list to original state */ + list=core_list_mergesort(list,cmp_idx,NULL); + /* CRC data content of list */ + finder=list->next; + while (finder) { + retval=crc16(list->info->data16,retval); + finder=finder->next; + } +#if CORE_DEBUG + ee_printf("List sort 2: %04x\n",retval); +#endif + return retval; +} +/* Function: core_list_init + Initialize list with data. + + Parameters: + blksize - Size of memory to be initialized. + memblock - Pointer to memory block. + seed - Actual values chosen depend on the seed parameter. + The seed parameter MUST be supplied from a source that cannot be determined at compile time + + Returns: + Pointer to the head of the list. + +*/ +list_head *core_list_init(ee_u32 blksize, list_head *memblock, ee_s16 seed) { + /* calculated pointers for the list */ + ee_u32 per_item=16+sizeof(struct list_data_s); + ee_u32 size=(blksize/per_item)-2; /* to accomodate systems with 64b pointers, and make sure same code is executed, set max list elements */ + list_head *memblock_end=memblock+size; + list_data *datablock=(list_data *)(memblock_end); + list_data *datablock_end=datablock+size; + /* some useful variables */ + ee_u32 i; + list_head *finder,*list=memblock; + list_data info; + + /* create a fake items for the list head and tail */ + list->next=NULL; + list->info=datablock; + list->info->idx=0x0000; + list->info->data16=(ee_s16)0x8080; + memblock++; + datablock++; + info.idx=0x7fff; + info.data16=(ee_s16)0xffff; + core_list_insert_new(list,&info,&memblock,&datablock,memblock_end,datablock_end); + + /* then insert size items */ + for (i=0; inext; + i=1; + while (finder->next!=NULL) { + if (iinfo->idx=i++; + else { + ee_u16 pat=(ee_u16)(i++ ^ seed); /* get a pseudo random number */ + finder->info->idx=0x3fff & (((i & 0x07) << 8) | pat); /* make sure the mixed items end up after the ones in sequence */ + } + finder=finder->next; + } + list = core_list_mergesort(list,cmp_idx,NULL); +#if CORE_DEBUG + ee_printf("Initialized list:\n"); + finder=list; + while (finder) { + ee_printf("[%04x,%04x]",finder->info->idx,(ee_u16)finder->info->data16); + finder=finder->next; + } + ee_printf("\n"); +#endif + return list; +} + +/* Function: core_list_insert + Insert an item to the list + + Parameters: + insert_point - where to insert the item. + info - data for the cell. + memblock - pointer for the list header + datablock - pointer for the list data + memblock_end - end of region for list headers + datablock_end - end of region for list data + + Returns: + Pointer to new item. +*/ +list_head *core_list_insert_new(list_head *insert_point, list_data *info, list_head **memblock, list_data **datablock + , list_head *memblock_end, list_data *datablock_end) { + list_head *newitem; + + if ((*memblock+1) >= memblock_end) + return NULL; + if ((*datablock+1) >= datablock_end) + return NULL; + + newitem=*memblock; + (*memblock)++; + newitem->next=insert_point->next; + insert_point->next=newitem; + + newitem->info=*datablock; + (*datablock)++; + copy_info(newitem->info,info); + + return newitem; +} + +/* Function: core_list_remove + Remove an item from the list. + + Operation: + For a singly linked list, remove by copying the data from the next item + over to the current cell, and unlinking the next item. + + Note: + since there is always a fake item at the end of the list, no need to check for NULL. + + Returns: + Removed item. +*/ +list_head *core_list_remove(list_head *item) { + list_data *tmp; + list_head *ret=item->next; + /* swap data pointers */ + tmp=item->info; + item->info=ret->info; + ret->info=tmp; + /* and eliminate item */ + item->next=item->next->next; + ret->next=NULL; + return ret; +} + +/* Function: core_list_undo_remove + Undo a remove operation. + + Operation: + Since we want each iteration of the benchmark to be exactly the same, + we need to be able to undo a remove. + Link the removed item back into the list, and switch the info items. + + Parameters: + item_removed - Return value from the + item_modified - List item that was modified during + + Returns: + The item that was linked back to the list. + +*/ +list_head *core_list_undo_remove(list_head *item_removed, list_head *item_modified) { + list_data *tmp; + /* swap data pointers */ + tmp=item_removed->info; + item_removed->info=item_modified->info; + item_modified->info=tmp; + /* and insert item */ + item_removed->next=item_modified->next; + item_modified->next=item_removed; + return item_removed; +} + +/* Function: core_list_find + Find an item in the list + + Operation: + Find an item by idx (if not 0) or specific data value + + Parameters: + list - list head + info - idx or data to find + + Returns: + Found item, or NULL if not found. +*/ +list_head *core_list_find(list_head *list,list_data *info) { + if (info->idx>=0) { + while (list && (list->info->idx != info->idx)) + list=list->next; + return list; + } else { + while (list && ((list->info->data16 & 0xff) != info->data16)) + list=list->next; + return list; + } +} +/* Function: core_list_reverse + Reverse a list + + Operation: + Rearrange the pointers so the list is reversed. + + Parameters: + list - list head + info - idx or data to find + + Returns: + Found item, or NULL if not found. +*/ + +list_head *core_list_reverse(list_head *list) { + list_head *next=NULL, *tmp; + while (list) { + tmp=list->next; + list->next=next; + next=list; + list=tmp; + } + return next; +} +/* Function: core_list_mergesort + Sort the list in place without recursion. + + Description: + Use mergesort, as for linked list this is a realistic solution. + Also, since this is aimed at embedded, care was taken to use iterative rather then recursive algorithm. + The sort can either return the list to original order (by idx) , + or use the data item to invoke other other algorithms and change the order of the list. + + Parameters: + list - list to be sorted. + cmp - cmp function to use + + Returns: + New head of the list. + + Note: + We have a special header for the list that will always be first, + but the algorithm could theoretically modify where the list starts. + + */ +list_head *core_list_mergesort(list_head *list, list_cmp cmp, core_results *res) { + list_head *p, *q, *e, *tail; + ee_s32 insize, nmerges, psize, qsize, i; + + insize = 1; + + while (1) { + p = list; + list = NULL; + tail = NULL; + + nmerges = 0; /* count number of merges we do in this pass */ + + while (p) { + nmerges++; /* there exists a merge to be done */ + /* step `insize' places along from p */ + q = p; + psize = 0; + for (i = 0; i < insize; i++) { + psize++; + q = q->next; + if (!q) break; + } + + /* if q hasn't fallen off end, we have two lists to merge */ + qsize = insize; + + /* now we have two lists; merge them */ + while (psize > 0 || (qsize > 0 && q)) { + + /* decide whether next element of merge comes from p or q */ + if (psize == 0) { + /* p is empty; e must come from q. */ + e = q; q = q->next; qsize--; + } else if (qsize == 0 || !q) { + /* q is empty; e must come from p. */ + e = p; p = p->next; psize--; + } else if (cmp(p->info,q->info,res) <= 0) { + /* First element of p is lower (or same); e must come from p. */ + e = p; p = p->next; psize--; + } else { + /* First element of q is lower; e must come from q. */ + e = q; q = q->next; qsize--; + } + + /* add the next element to the merged list */ + if (tail) { + tail->next = e; + } else { + list = e; + } + tail = e; + } + + /* now p has stepped `insize' places along, and q has too */ + p = q; + } + + tail->next = NULL; + + /* If we have done only one merge, we're finished. */ + if (nmerges <= 1) /* allow for nmerges==0, the empty list case */ + return list; + + /* Otherwise repeat, merging lists twice the size */ + insize *= 2; + } +#if COMPILER_REQUIRES_SORT_RETURN + return list; +#endif +} +/* +Author : Shay Gal-On, EEMBC + +This file is part of EEMBC(R) and CoreMark(TM), which are Copyright (C) 2009 +All rights reserved. + +EEMBC CoreMark Software is a product of EEMBC and is provided under the terms of the +CoreMark License that is distributed with the official EEMBC COREMARK Software release. +If you received this EEMBC CoreMark Software without the accompanying CoreMark License, +you must discontinue use and download the official release from www.coremark.org. + +Also, if you are publicly displaying scores generated from the EEMBC CoreMark software, +make sure that you are in compliance with Run and Reporting rules specified in the accompanying readme.txt file. + +EEMBC +4354 Town Center Blvd. Suite 114-200 +El Dorado Hills, CA, 95762 +*/ +/* File: core_main.c + This file contains the framework to acquire a block of memory, seed initial parameters, tun t he benchmark and report the results. +*/ +//#include "coremark.h" + +/* Function: iterate + Run the benchmark for a specified number of iterations. + + Operation: + For each type of benchmarked algorithm: + a - Initialize the data block for the algorithm. + b - Execute the algorithm N times. + + Returns: + NULL. +*/ +static ee_u16 list_known_crc[] = {(ee_u16)0xd4b0,(ee_u16)0x3340,(ee_u16)0x6a79,(ee_u16)0xe714,(ee_u16)0xe3c1}; +static ee_u16 matrix_known_crc[] = {(ee_u16)0xbe52,(ee_u16)0x1199,(ee_u16)0x5608,(ee_u16)0x1fd7,(ee_u16)0x0747}; +static ee_u16 state_known_crc[] = {(ee_u16)0x5e47,(ee_u16)0x39bf,(ee_u16)0xe5a4,(ee_u16)0x8e3a,(ee_u16)0x8d84}; +void *iterate(void *pres) { + ee_u32 i; + ee_u16 crc; + core_results *res=(core_results *)pres; + ee_u32 iterations=res->iterations; + res->crc=0; + res->crclist=0; + res->crcmatrix=0; + res->crcstate=0; + + for (i=0; icrc=crcu16(crc,res->crc); + crc=core_bench_list(res,-1); + res->crc=crcu16(crc,res->crc); + if (i==0) res->crclist=res->crc; + } + return NULL; +} + +#if (SEED_METHOD==SEED_ARG) +ee_s32 get_seed_args(int i, int argc, char *argv[]); +#define get_seed(x) (ee_s16)get_seed_args(x,argc,argv) +#define get_seed_32(x) get_seed_args(x,argc,argv) +#else /* via function or volatile */ +ee_s32 get_seed_32(int i); +#define get_seed(x) (ee_s16)get_seed_32(x) +#endif + +#if (MEM_METHOD==MEM_STATIC) +ee_u8 static_memblk[TOTAL_DATA_SIZE]; +#endif +char *mem_name[3] = {"Static","Heap","Stack"}; +/* Function: main + Main entry routine for the benchmark. + This function is responsible for the following steps: + + 1 - Initialize input seeds from a source that cannot be determined at compile time. + 2 - Initialize memory block for use. + 3 - Run and time the benchmark. + 4 - Report results, testing the validity of the output if the seeds are known. + + Arguments: + 1 - first seed : Any value + 2 - second seed : Must be identical to first for iterations to be identical + 3 - third seed : Any value, should be at least an order of magnitude less then the input size, but bigger then 32. + 4 - Iterations : Special, if set to 0, iterations will be automatically determined such that the benchmark will run between 10 to 100 secs + +*/ + +#if MAIN_HAS_NOARGC +MAIN_RETURN_TYPE main(void) { + int argc=0; + char *argv[1]; +#else +MAIN_RETURN_TYPE main(int argc, char *argv[]) { +#endif + ee_u16 i,j=0,num_algorithms=0; + ee_s16 known_id=-1,total_errors=0; + ee_u16 seedcrc=0; + CORE_TICKS total_time; + core_results results[MULTITHREAD]; +#if (MEM_METHOD==MEM_STACK) + ee_u8 stack_memblock[TOTAL_DATA_SIZE*MULTITHREAD]; +#endif + /* first call any initializations needed */ + portable_init(&(results[0].port), &argc, argv); + /* First some checks to make sure benchmark will run ok */ + if (sizeof(struct list_head_s)>128) { + ee_printf("list_head structure too big for comparable data!\n"); + return MAIN_RETURN_VAL; + } + results[0].seed1=get_seed(1); + results[0].seed2=get_seed(2); + results[0].seed3=get_seed(3); + results[0].iterations=get_seed_32(4); +#if CORE_DEBUG + results[0].iterations=1; +#endif + results[0].execs=get_seed_32(5); + if (results[0].execs==0) { /* if not supplied, execute all algorithms */ + results[0].execs=ALL_ALGORITHMS_MASK; + } + /* put in some default values based on one seed only for easy testing */ + if ((results[0].seed1==0) && (results[0].seed2==0) && (results[0].seed3==0)) { /* validation run */ + results[0].seed1=0; + results[0].seed2=0; + results[0].seed3=0x66; + } + if ((results[0].seed1==1) && (results[0].seed2==0) && (results[0].seed3==0)) { /* perfromance run */ + results[0].seed1=0x3415; + results[0].seed2=0x3415; + results[0].seed3=0x66; + } +#if (MEM_METHOD==MEM_STATIC) + results[0].memblock[0]=(void *)static_memblk; + results[0].size=TOTAL_DATA_SIZE; + results[0].err=0; + #if (MULTITHREAD>1) + #error "Cannot use a static data area with multiple contexts!" + #endif +#elif (MEM_METHOD==MEM_MALLOC) + for (i=0 ; i1) + if (default_num_contexts>MULTITHREAD) { + default_num_contexts=MULTITHREAD; + } + for (i=0 ; i=0) { + for (i=0 ; i 0) + ee_printf("Iterations/Sec : %f\n",default_num_contexts*results[0].iterations/time_in_secs(total_time)); +#else + ee_printf("Total time (secs): %d\n",time_in_secs(total_time)); + if (time_in_secs(total_time) > 0) +// ee_printf("Iterations/Sec : %d\n",default_num_contexts*results[0].iterations/time_in_secs(total_time)); + ee_printf("Iterat/Sec/MHz : %d.%d\n",1000*default_num_contexts*results[0].iterations/time_in_secs(total_time), + 100000*default_num_contexts*results[0].iterations/time_in_secs(total_time) % 100); +#endif + if (time_in_secs(total_time) < 10) { + ee_printf("ERROR! Must execute for at least 10 secs for a valid result!\n"); + total_errors++; + } + + ee_printf("Iterations : %u\n",(ee_u32)default_num_contexts*results[0].iterations); + ee_printf("Compiler version : %s\n",COMPILER_VERSION); + ee_printf("Compiler flags : %s\n",COMPILER_FLAGS); +#if (MULTITHREAD>1) + ee_printf("Parallel %s : %d\n",PARALLEL_METHOD,default_num_contexts); +#endif + ee_printf("Memory location : %s\n",MEM_LOCATION); + /* output for verification */ + ee_printf("seedcrc : 0x%04x\n",seedcrc); + if (results[0].execs & ID_LIST) + for (i=0 ; i1) + ee_printf(" / %d:%s",default_num_contexts,PARALLEL_METHOD); +#endif + ee_printf("\n"); + } +#endif + } + if (total_errors>0) + ee_printf("Errors detected\n"); + if (total_errors<0) + ee_printf("Cannot validate operation for these seed values, please compare with results on a known platform.\n"); + +#if (MEM_METHOD==MEM_MALLOC) + for (i=0 ; i>(from)) & (~(0xffffffff << (to)))) + +#if CORE_DEBUG +void printmat(MATDAT *A, ee_u32 N, char *name) { + ee_u32 i,j; + ee_printf("Matrix %s [%dx%d]:\n",name,N,N); + for (i=0; i N times, + changing the matrix values slightly by a constant amount each time. +*/ +ee_u16 core_bench_matrix(mat_params *p, ee_s16 seed, ee_u16 crc) { + ee_u32 N=p->N; + MATRES *C=p->C; + MATDAT *A=p->A; + MATDAT *B=p->B; + MATDAT val=(MATDAT)seed; + + crc=crc16(matrix_test(N,C,A,B,val),crc); + + return crc; +} + +/* Function: matrix_test + Perform matrix manipulation. + + Parameters: + N - Dimensions of the matrix. + C - memory for result matrix. + A - input matrix + B - operator matrix (not changed during operations) + + Returns: + A CRC value that captures all results calculated in the function. + In particular, crc of the value calculated on the result matrix + after each step by . + + Operation: + + 1 - Add a constant value to all elements of a matrix. + 2 - Multiply a matrix by a constant. + 3 - Multiply a matrix by a vector. + 4 - Multiply a matrix by a matrix. + 5 - Add a constant value to all elements of a matrix. + + After the last step, matrix A is back to original contents. +*/ +ee_s16 matrix_test(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B, MATDAT val) { + ee_u16 crc=0; + MATDAT clipval=matrix_big(val); + + matrix_add_const(N,A,val); /* make sure data changes */ +#if CORE_DEBUG + printmat(A,N,"matrix_add_const"); +#endif + matrix_mul_const(N,C,A,val); + crc=crc16(matrix_sum(N,C,clipval),crc); +#if CORE_DEBUG + printmatC(C,N,"matrix_mul_const"); +#endif + matrix_mul_vect(N,C,A,B); + crc=crc16(matrix_sum(N,C,clipval),crc); +#if CORE_DEBUG + printmatC(C,N,"matrix_mul_vect"); +#endif + matrix_mul_matrix(N,C,A,B); + crc=crc16(matrix_sum(N,C,clipval),crc); +#if CORE_DEBUG + printmatC(C,N,"matrix_mul_matrix"); +#endif + matrix_mul_matrix_bitextract(N,C,A,B); + crc=crc16(matrix_sum(N,C,clipval),crc); +#if CORE_DEBUG + printmatC(C,N,"matrix_mul_matrix_bitextract"); +#endif + + matrix_add_const(N,A,-val); /* return matrix to initial value */ + return crc; +} + +/* Function : matrix_init + Initialize the memory block for matrix benchmarking. + + Parameters: + blksize - Size of memory to be initialized. + memblk - Pointer to memory block. + seed - Actual values chosen depend on the seed parameter. + p - pointers to containing initialized matrixes. + + Returns: + Matrix dimensions. + + Note: + The seed parameter MUST be supplied from a source that cannot be determined at compile time +*/ +ee_u32 core_init_matrix(ee_u32 blksize, void *memblk, ee_s32 seed, mat_params *p) { + ee_u32 N=0; + MATDAT *A; + MATDAT *B; + ee_s32 order=1; + MATDAT val; + ee_u32 i=0,j=0; + if (seed==0) + seed=1; + while (jA=A; + p->B=B; + p->C=(MATRES *)align_mem(B+N*N); + p->N=N; +#if CORE_DEBUG + printmat(A,N,"A"); + printmat(B,N,"B"); +#endif + return N; +} + +/* Function: matrix_sum + Calculate a function that depends on the values of elements in the matrix. + + For each element, accumulate into a temporary variable. + + As long as this value is under the parameter clipval, + add 1 to the result if the element is bigger then the previous. + + Otherwise, reset the accumulator and add 10 to the result. +*/ +ee_s16 matrix_sum(ee_u32 N, MATRES *C, MATDAT clipval) { + MATRES tmp=0,prev=0,cur=0; + ee_s16 ret=0; + ee_u32 i,j; + for (i=0; iclipval) { + ret+=10; + tmp=0; + } else { + ret += (cur>prev) ? 1 : 0; + } + prev=cur; + } + } + return ret; +} + +/* Function: matrix_mul_const + Multiply a matrix by a constant. + This could be used as a scaler for instance. +*/ +void matrix_mul_const(ee_u32 N, MATRES *C, MATDAT *A, MATDAT val) { + ee_u32 i,j; + for (i=0; i0) { + for(i=0;i>3) & 0x3]; + next=4; + break; + case 3: /* float */ + case 4: /* float */ + buf=floatpat[(seed>>3) & 0x3]; + next=8; + break; + case 5: /* scientific */ + case 6: /* scientific */ + buf=scipat[(seed>>3) & 0x3]; + next=8; + break; + case 7: /* invalid */ + buf=errpat[(seed>>3) & 0x3]; + next=8; + break; + default: /* Never happen, just to make some compilers happy */ + break; + } + } + size++; + while (total='0') & (c<='9')) ? 1 : 0; + return retval; +} + +/* Function: core_state_transition + Actual state machine. + + The state machine will continue scanning until either: + 1 - an invalid input is detcted. + 2 - a valid number has been detected. + + The input pointer is updated to point to the end of the token, and the end state is returned (either specific format determined or invalid). +*/ + +enum CORE_STATE core_state_transition( ee_u8 **instr , ee_u32 *transition_count) { + ee_u8 *str=*instr; + ee_u8 NEXT_SYMBOL; + enum CORE_STATE state=CORE_START; + for( ; *str && state != CORE_INVALID; str++ ) { + NEXT_SYMBOL = *str; + if (NEXT_SYMBOL==',') /* end of this input */ { + str++; + break; + } + switch(state) { + case CORE_START: + if(ee_isdigit(NEXT_SYMBOL)) { + state = CORE_INT; + } + else if( NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-' ) { + state = CORE_S1; + } + else if( NEXT_SYMBOL == '.' ) { + state = CORE_FLOAT; + } + else { + state = CORE_INVALID; + transition_count[CORE_INVALID]++; + } + transition_count[CORE_START]++; + break; + case CORE_S1: + if(ee_isdigit(NEXT_SYMBOL)) { + state = CORE_INT; + transition_count[CORE_S1]++; + } + else if( NEXT_SYMBOL == '.' ) { + state = CORE_FLOAT; + transition_count[CORE_S1]++; + } + else { + state = CORE_INVALID; + transition_count[CORE_S1]++; + } + break; + case CORE_INT: + if( NEXT_SYMBOL == '.' ) { + state = CORE_FLOAT; + transition_count[CORE_INT]++; + } + else if(!ee_isdigit(NEXT_SYMBOL)) { + state = CORE_INVALID; + transition_count[CORE_INT]++; + } + break; + case CORE_FLOAT: + if( NEXT_SYMBOL == 'E' || NEXT_SYMBOL == 'e' ) { + state = CORE_S2; + transition_count[CORE_FLOAT]++; + } + else if(!ee_isdigit(NEXT_SYMBOL)) { + state = CORE_INVALID; + transition_count[CORE_FLOAT]++; + } + break; + case CORE_S2: + if( NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-' ) { + state = CORE_EXPONENT; + transition_count[CORE_S2]++; + } + else { + state = CORE_INVALID; + transition_count[CORE_S2]++; + } + break; + case CORE_EXPONENT: + if(ee_isdigit(NEXT_SYMBOL)) { + state = CORE_SCIENTIFIC; + transition_count[CORE_EXPONENT]++; + } + else { + state = CORE_INVALID; + transition_count[CORE_EXPONENT]++; + } + break; + case CORE_SCIENTIFIC: + if(!ee_isdigit(NEXT_SYMBOL)) { + state = CORE_INVALID; + transition_count[CORE_INVALID]++; + } + break; + default: + break; + } + } + *instr=str; + return state; +} +/* +Author : Shay Gal-On, EEMBC + +This file is part of EEMBC(R) and CoreMark(TM), which are Copyright (C) 2009 +All rights reserved. + +EEMBC CoreMark Software is a product of EEMBC and is provided under the terms of the +CoreMark License that is distributed with the official EEMBC COREMARK Software release. +If you received this EEMBC CoreMark Software without the accompanying CoreMark License, +you must discontinue use and download the official release from www.coremark.org. + +Also, if you are publicly displaying scores generated from the EEMBC CoreMark software, +make sure that you are in compliance with Run and Reporting rules specified in the accompanying readme.txt file. + +EEMBC +4354 Town Center Blvd. Suite 114-200 +El Dorado Hills, CA, 95762 +*/ +//#include "coremark.h" +/* Function: get_seed + Get a values that cannot be determined at compile time. + + Since different embedded systems and compilers are used, 3 different methods are provided: + 1 - Using a volatile variable. This method is only valid if the compiler is forced to generate code that + reads the value of a volatile variable from memory at run time. + Please note, if using this method, you would need to modify core_portme.c to generate training profile. + 2 - Command line arguments. This is the preferred method if command line arguments are supported. + 3 - System function. If none of the first 2 methods is available on the platform, + a system function which is not a stub can be used. + + e.g. read the value on GPIO pins connected to switches, or invoke special simulator functions. +*/ +#if (SEED_METHOD==SEED_VOLATILE) + extern volatile ee_s32 seed1_volatile; + extern volatile ee_s32 seed2_volatile; + extern volatile ee_s32 seed3_volatile; + extern volatile ee_s32 seed4_volatile; + extern volatile ee_s32 seed5_volatile; + ee_s32 get_seed_32(int i) { + ee_s32 retval; + switch (i) { + case 1: + retval=seed1_volatile; + break; + case 2: + retval=seed2_volatile; + break; + case 3: + retval=seed3_volatile; + break; + case 4: + retval=seed4_volatile; + break; + case 5: + retval=seed5_volatile; + break; + default: + retval=0; + break; + } + return retval; + } +#elif (SEED_METHOD==SEED_ARG) +ee_s32 parseval(char *valstring) { + ee_s32 retval=0; + ee_s32 neg=1; + int hexmode=0; + if (*valstring == '-') { + neg=-1; + valstring++; + } + if ((valstring[0] == '0') && (valstring[1] == 'x')) { + hexmode=1; + valstring+=2; + } + /* first look for digits */ + if (hexmode) { + while (((*valstring >= '0') && (*valstring <= '9')) || ((*valstring >= 'a') && (*valstring <= 'f'))) { + ee_s32 digit=*valstring-'0'; + if (digit>9) + digit=10+*valstring-'a'; + retval*=16; + retval+=digit; + valstring++; + } + } else { + while ((*valstring >= '0') && (*valstring <= '9')) { + ee_s32 digit=*valstring-'0'; + retval*=10; + retval+=digit; + valstring++; + } + } + /* now add qualifiers */ + if (*valstring=='K') + retval*=1024; + if (*valstring=='M') + retval*=1024*1024; + + retval*=neg; + return retval; +} + +ee_s32 get_seed_args(int i, int argc, char *argv[]) { + if (argc>i) + return parseval(argv[i]); + return 0; +} + +#elif (SEED_METHOD==SEED_FUNC) +/* If using OS based function, you must define and implement the functions below in core_portme.h and core_portme.c ! */ +ee_s32 get_seed_32(int i) { + ee_s32 retval; + switch (i) { + case 1: + retval=portme_sys1(); + break; + case 2: + retval=portme_sys2(); + break; + case 3: + retval=portme_sys3(); + break; + case 4: + retval=portme_sys4(); + break; + case 5: + retval=portme_sys5(); + break; + default: + retval=0; + break; + } + return retval; +} +#endif + +/* Function: crc* + Service functions to calculate 16b CRC code. + +*/ +ee_u16 crcu8(ee_u8 data, ee_u16 crc ) +{ + ee_u8 i=0,x16=0,carry=0; + + for (i = 0; i < 8; i++) + { + x16 = (ee_u8)((data & 1) ^ ((ee_u8)crc & 1)); + data >>= 1; + + if (x16 == 1) + { + crc ^= 0x4002; + carry = 1; + } + else + carry = 0; + crc >>= 1; + if (carry) + crc |= 0x8000; + else + crc &= 0x7fff; + } + return crc; +} +ee_u16 crcu16(ee_u16 newval, ee_u16 crc) { + crc=crcu8( (ee_u8) (newval) ,crc); + crc=crcu8( (ee_u8) ((newval)>>8) ,crc); + return crc; +} +ee_u16 crcu32(ee_u32 newval, ee_u16 crc) { + crc=crc16((ee_s16) newval ,crc); + crc=crc16((ee_s16) (newval>>16) ,crc); + return crc; +} +ee_u16 crc16(ee_s16 newval, ee_u16 crc) { + return crcu16((ee_u16)newval, crc); +} + +ee_u8 check_data_types() { + ee_u8 retval=0; + if (sizeof(ee_u8) != 1) { + ee_printf("ERROR: ee_u8 is not an 8b datatype!\n"); + retval++; + } + if (sizeof(ee_u16) != 2) { + ee_printf("ERROR: ee_u16 is not a 16b datatype!\n"); + retval++; + } + if (sizeof(ee_s16) != 2) { + ee_printf("ERROR: ee_s16 is not a 16b datatype!\n"); + retval++; + } + if (sizeof(ee_s32) != 4) { + ee_printf("ERROR: ee_s32 is not a 32b datatype!\n"); + retval++; + } + if (sizeof(ee_u32) != 4) { + ee_printf("ERROR: ee_u32 is not a 32b datatype!\n"); + retval++; + } + if (sizeof(ee_ptr_int) != sizeof(int *)) { + ee_printf("ERROR: ee_ptr_int is not a datatype that holds an int pointer!\n"); + retval++; + } + if (retval>0) { + ee_printf("ERROR: Please modify the datatypes in core_portme.h!\n"); + } + return retval; +} +/* + File : core_portme.c +*/ +/* + Author : Shay Gal-On, EEMBC + Legal : TODO! +*/ +#include +#include +//#include "coremark.h" + +#if VALIDATION_RUN + volatile ee_s32 seed1_volatile=0x3415; + volatile ee_s32 seed2_volatile=0x3415; + volatile ee_s32 seed3_volatile=0x66; +#endif +#if PERFORMANCE_RUN + volatile ee_s32 seed1_volatile=0x0; + volatile ee_s32 seed2_volatile=0x0; + volatile ee_s32 seed3_volatile=0x66; +#endif +#if PROFILE_RUN + volatile ee_s32 seed1_volatile=0x8; + volatile ee_s32 seed2_volatile=0x8; + volatile ee_s32 seed3_volatile=0x8; +#endif + volatile ee_s32 seed4_volatile=ITERATIONS; + volatile ee_s32 seed5_volatile=0; +/* Porting : Timing functions + How to capture time and convert to seconds must be ported to whatever is supported by the platform. + e.g. Read value from on board RTC, read value from cpu clock cycles performance counter etc. + Sample implementation for standard time.h and windows.h definitions included. +*/ +/* Define : TIMER_RES_DIVIDER + Divider to trade off timer resolution and total time that can be measured. + + Use lower values to increase resolution, but make sure that overflow does not occur. + If there are issues with the return value overflowing, increase this value. + */ +//#define NSECS_PER_SEC CLOCKS_PER_SEC +#define NSECS_PER_SEC 1000000000 +#define CORETIMETYPE clock_t +//#define GETMYTIME(_t) (*_t=clock()) +#define GETMYTIME(_t) (*_t=0) +#define MYTIMEDIFF(fin,ini) ((fin)-(ini)) +#define TIMER_RES_DIVIDER 1 +#define SAMPLE_TIME_IMPLEMENTATION 1 +//#define EE_TICKS_PER_SEC (NSECS_PER_SEC / TIMER_RES_DIVIDER) + +#define EE_TICKS_PER_SEC 1000 + +/** Define Host specific (POSIX), or target specific global time variables. */ +static CORETIMETYPE start_time_val, stop_time_val; + +/* Function : start_time + This function will be called right before starting the timed portion of the benchmark. + + Implementation may be capturing a system timer (as implemented in the example code) + or zeroing some system parameters - e.g. setting the cpu clocks cycles to 0. +*/ +void start_time(void) { +uint32_t mcyclel; + asm volatile ("csrr %0,mcycle" : "=r" (mcyclel) ); + start_time_val = mcyclel; +} +/* Function : stop_time + This function will be called right after ending the timed portion of the benchmark. + + Implementation may be capturing a system timer (as implemented in the example code) + or other system parameters - e.g. reading the current value of cpu cycles counter. +*/ +void stop_time(void) { +uint32_t mcyclel; + asm volatile ("csrr %0,mcycle" : "=r" (mcyclel) ); + stop_time_val = mcyclel; +} +/* Function : get_time + Return an abstract "ticks" number that signifies time on the system. + + Actual value returned may be cpu cycles, milliseconds or any other value, + as long as it can be converted to seconds by . + This methodology is taken to accomodate any hardware or simulated platform. + The sample implementation returns millisecs by default, + and the resolution is controlled by +*/ +CORE_TICKS get_time(void) { + CORE_TICKS elapsed=(CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val)); + return elapsed; +} +/* Function : time_in_secs + Convert the value returned by get_time to seconds. + + The type is used to accomodate systems with no support for floating point. + Default implementation implemented by the EE_TICKS_PER_SEC macro above. +*/ +secs_ret time_in_secs(CORE_TICKS ticks) { + secs_ret retval=((secs_ret)ticks) / (secs_ret)EE_TICKS_PER_SEC; + return retval; +} + +ee_u32 default_num_contexts=1; + +/* Function : portable_init + Target specific initialization code + Test for some common mistakes. +*/ +void portable_init(core_portable *p, int *argc, char *argv[]) +{ + if (sizeof(ee_ptr_int) != sizeof(ee_u8 *)) { + ee_printf("ERROR! Please define ee_ptr_int to a type that holds a pointer!\n"); + } + if (sizeof(ee_u32) != 4) { + ee_printf("ERROR! Please define ee_u32 to a 32b unsigned type!\n"); + } + p->portable_id=1; +} +/* Function : portable_fini + Target specific final code +*/ +void portable_fini(core_portable *p) +{ + p->portable_id=0; +} + + +#include + +// Special address. Writing (store byte instruction) to this address +// causes the simulator to write to the console. +volatile char __whisper_console_io = 0; + + +static int +whisperPutc(char c) +{ +// __whisper_console_io = c; +// __whisper_console_io = c; + *(volatile char*)(STDOUT) = c; + return c; +} + + +static int +whisperPuts(const char* s) +{ + while (*s) + whisperPutc(*s++); + return 1; +} + + +static int +whisperPrintDecimal(int value) +{ + char buffer[20]; + int charCount = 0; + + unsigned neg = value < 0; + if (neg) + { + value = -value; + whisperPutc('-'); + } + + do + { + char c = '0' + (value % 10); + value = value / 10; + buffer[charCount++] = c; + } + while (value); + + char* p = buffer + charCount - 1; + for (unsigned i = 0; i < charCount; ++i) + whisperPutc(*p--); + + if (neg) + charCount++; + + return charCount; +} + + +static int +whisperPrintInt(int value, int base) +{ + if (base == 10) + return whisperPrintDecimal(value); + + char buffer[20]; + int charCount = 0; + + unsigned uu = value; + + if (base == 8) + { + do + { + char c = '0' + (uu & 7); + buffer[charCount++] = c; + uu >>= 3; + } + while (uu); + } + else if (base == 16) + { + do + { + int digit = uu & 0xf; + char c = digit < 10 ? '0' + digit : 'a' + digit; + buffer[charCount++] = c; + uu >>= 4; + } + while (uu); + } + else + return -1; + + char* p = buffer + charCount - 1; + for (unsigned i = 0; i < charCount; ++i) + whisperPutc(*p--); + + return charCount; +} + + +int +whisperPrintfImpl(const char* format, va_list ap) +{ + int count = 0; // Printed character count + + for (const char* fp = format; *fp; fp++) + { + if (*fp != '%') + { + whisperPutc(*fp); + ++count; + continue; + } + + ++fp; // Skip % + + if (*fp == 0) + break; + + if (*fp == '%') + { + whisperPutc('%'); + continue; + } + + if (*fp == '-') + { + fp++; // Pad right not yet implemented. + } + + while (*fp == '0') + { + fp++; // Pad zero not yet implented. + } + + if (*fp == '*') + { + int width = va_arg(ap, int); + fp++; // Width not yet implemented. + } + else + { + while (*fp >= '0' && *fp <= '9') + ++fp; // Width not yet implemented. + } + + switch (*fp) + { + case 'd': + count += whisperPrintDecimal(va_arg(ap, int)); + break; + + case 'u': + count += whisperPrintDecimal((unsigned) va_arg(ap, unsigned)); + break; + + case 'x': + case 'X': + count += whisperPrintInt(va_arg(ap, int), 16); + break; + + case 'o': + count += whisperPrintInt(va_arg(ap, int), 8); + break; + + case 'c': + whisperPutc(va_arg(ap, int)); + ++count; + break; + + case 's': + count += whisperPuts(va_arg(ap, char*)); + break; + } + } + + return count; +} + + +int +whisperPrintf(const char* format, ...) +{ + va_list ap; + + va_start(ap, format); + int code = whisperPrintfImpl(format, ap); + va_end(ap); + + return code; +} + + +int +printf(const char* format, ...) +{ + va_list ap; + + va_start(ap, format); + int code = whisperPrintfImpl(format, ap); + va_end(ap); + + return code; +} + + +void* memset(void* s, int c, size_t n) +{ + asm("mv t0, a0"); + asm("add a2, a2, a0"); // end = s + n + asm(".memset_loop: bge a0, a2, .memset_end"); + asm("sb a1, 0(a0)"); + asm("addi a0, a0, 1"); + asm("j .memset_loop"); + asm(".memset_end:"); + asm("mv a0, t0"); + asm("jr ra"); +} diff --git a/testbench/asm/cmark_dccm.c b/testbench/asm/cmark_dccm.c new file mode 120000 index 0000000..712dfb9 --- /dev/null +++ b/testbench/asm/cmark_dccm.c @@ -0,0 +1 @@ +cmark.c \ No newline at end of file diff --git a/testbench/asm/cmark_dccm.ld b/testbench/asm/cmark_dccm.ld new file mode 120000 index 0000000..ae51d23 --- /dev/null +++ b/testbench/asm/cmark_dccm.ld @@ -0,0 +1 @@ +hello_world_dccm.ld \ No newline at end of file diff --git a/testbench/asm/cmark_iccm.c b/testbench/asm/cmark_iccm.c new file mode 100644 index 0000000..6154290 --- /dev/null +++ b/testbench/asm/cmark_iccm.c @@ -0,0 +1,2404 @@ +#include "defines.h" + +#define ITERATIONS 1 +extern int STACK; +void main(); + + +#define STDOUT 0xd0580000 + +__asm (".section .text_init, \"ax\""); +__asm (".global _start"); +__asm ("_start:"); + +// Enable Caches in MRAC +__asm ("li t0, 0x5f555555"); +__asm ("csrw 0x7c0, t0"); + +// Set stack pointer. +__asm ("la sp, STACK"); + +__asm ("call main"); + +// Write 0xff to STDOUT for TB to termiate test. +__asm (".global _finish"); +__asm ("_finish:"); +__asm ("li t0, 0xd0580000"); +__asm ("addi t1, zero, 0xff"); +__asm ("sb t1, 0(t0)"); +__asm ("beq x0, x0, _finish"); +__asm (".rept 10"); +__asm ("nop"); +__asm (".endr"); +__asm (".section .text"); + + +/* +Author : Shay Gal-On, EEMBC + +This file is part of EEMBC(R) and CoreMark(TM), which are Copyright (C) 2009 +All rights reserved. + +EEMBC CoreMark Software is a product of EEMBC and is provided under the terms of the +CoreMark License that is distributed with the official EEMBC COREMARK Software release. +If you received this EEMBC CoreMark Software without the accompanying CoreMark License, +you must discontinue use and download the official release from www.coremark.org. + +Also, if you are publicly displaying scores generated from the EEMBC CoreMark software, +make sure that you are in compliance with Run and Reporting rules specified in the accompanying readme.txt file. + +EEMBC +4354 Town Center Blvd. Suite 114-200 +El Dorado Hills, CA, 95762 +*/ + +//#include "/wd/users/jrahmeh/coremark_v1.0/riscv/coremark.h" + +/* +Author : Shay Gal-On, EEMBC + +This file is part of EEMBC(R) and CoreMark(TM), which are Copyright (C) 2009 +All rights reserved. + +EEMBC CoreMark Software is a product of EEMBC and is provided under the terms of the +CoreMark License that is distributed with the official EEMBC COREMARK Software release. +If you received this EEMBC CoreMark Software without the accompanying CoreMark License, +you must discontinue use and download the official release from www.coremark.org. + +Also, if you are publicly displaying scores generated from the EEMBC CoreMark software, +make sure that you are in compliance with Run and Reporting rules specified in the accompanying readme.txt file. + +EEMBC +4354 Town Center Blvd. Suite 114-200 +El Dorado Hills, CA, 95762 +*/ +/* Topic: Description + This file contains declarations of the various benchmark functions. +*/ + +/* Configuration: TOTAL_DATA_SIZE + Define total size for data algorithms will operate on +*/ +#ifndef TOTAL_DATA_SIZE +#define TOTAL_DATA_SIZE 2*1000 +#endif + +#define SEED_ARG 0 +#define SEED_FUNC 1 +#define SEED_VOLATILE 2 + +#define MEM_STATIC 0 +#define MEM_MALLOC 1 +#define MEM_STACK 2 + +/* File : core_portme.h */ + +/* + Author : Shay Gal-On, EEMBC + Legal : TODO! +*/ +/* Topic : Description + This file contains configuration constants required to execute on different platforms +*/ +#ifndef CORE_PORTME_H +#define CORE_PORTME_H +/************************/ +/* Data types and settings */ +/************************/ +/* Configuration : HAS_FLOAT + Define to 1 if the platform supports floating point. +*/ +#ifndef HAS_FLOAT +#define HAS_FLOAT 0 +#endif +/* Configuration : HAS_TIME_H + Define to 1 if platform has the time.h header file, + and implementation of functions thereof. +*/ +#ifndef HAS_TIME_H +#define HAS_TIME_H 0 +#endif +/* Configuration : USE_CLOCK + Define to 1 if platform has the time.h header file, + and implementation of functions thereof. +*/ +#ifndef USE_CLOCK +#define USE_CLOCK 0 +#endif +/* Configuration : HAS_STDIO + Define to 1 if the platform has stdio.h. +*/ +#ifndef HAS_STDIO +#define HAS_STDIO 0 +#endif +/* Configuration : HAS_PRINTF + Define to 1 if the platform has stdio.h and implements the printf function. +*/ +#ifndef HAS_PRINTF +#define HAS_PRINTF 1 +int whisperPrintf(const char* format, ...); +#define ee_printf whisperPrintf +#endif + +/* Configuration : CORE_TICKS + Define type of return from the timing functions. + */ +#include +typedef clock_t CORE_TICKS; + +/* Definitions : COMPILER_VERSION, COMPILER_FLAGS, MEM_LOCATION + Initialize these strings per platform +*/ +#ifndef COMPILER_VERSION + #ifdef __GNUC__ + #define COMPILER_VERSION "GCC"__VERSION__ + #else + #define COMPILER_VERSION "Please put compiler version here (e.g. gcc 4.1)" + #endif +#endif +#ifndef COMPILER_FLAGS + #define COMPILER_FLAGS "-O2" +#endif + +#ifndef MEM_LOCATION +// #define MEM_LOCATION "STACK" + #define MEM_LOCATION "STATIC" +#endif + +/* Data Types : + To avoid compiler issues, define the data types that need ot be used for 8b, 16b and 32b in . + + *Imprtant* : + ee_ptr_int needs to be the data type used to hold pointers, otherwise coremark may fail!!! +*/ +typedef signed short ee_s16; +typedef unsigned short ee_u16; +typedef signed int ee_s32; +typedef double ee_f32; +typedef unsigned char ee_u8; +typedef unsigned int ee_u32; +typedef ee_u32 ee_ptr_int; +typedef size_t ee_size_t; +/* align_mem : + This macro is used to align an offset to point to a 32b value. It is used in the Matrix algorithm to initialize the input memory blocks. +*/ +#define align_mem(x) (void *)(4 + (((ee_ptr_int)(x) - 1) & ~3)) + +/* Configuration : SEED_METHOD + Defines method to get seed values that cannot be computed at compile time. + + Valid values : + SEED_ARG - from command line. + SEED_FUNC - from a system function. + SEED_VOLATILE - from volatile variables. +*/ +#ifndef SEED_METHOD +#define SEED_METHOD SEED_VOLATILE +#endif + +/* Configuration : MEM_METHOD + Defines method to get a block of memry. + + Valid values : + MEM_MALLOC - for platforms that implement malloc and have malloc.h. + MEM_STATIC - to use a static memory array. + MEM_STACK - to allocate the data block on the stack (NYI). +*/ +#ifndef MEM_METHOD +//#define MEM_METHOD MEM_STACK +#define MEM_METHOD MEM_STATIC +#endif + +/* Configuration : MULTITHREAD + Define for parallel execution + + Valid values : + 1 - only one context (default). + N>1 - will execute N copies in parallel. + + Note : + If this flag is defined to more then 1, an implementation for launching parallel contexts must be defined. + + Two sample implementations are provided. Use or to enable them. + + It is valid to have a different implementation of and in , + to fit a particular architecture. +*/ +#ifndef MULTITHREAD +#define MULTITHREAD 1 +#define USE_PTHREAD 0 +#define USE_FORK 0 +#define USE_SOCKET 0 +#endif + +/* Configuration : MAIN_HAS_NOARGC + Needed if platform does not support getting arguments to main. + + Valid values : + 0 - argc/argv to main is supported + 1 - argc/argv to main is not supported + + Note : + This flag only matters if MULTITHREAD has been defined to a value greater then 1. +*/ +#ifndef MAIN_HAS_NOARGC +#define MAIN_HAS_NOARGC 1 +#endif + +/* Configuration : MAIN_HAS_NORETURN + Needed if platform does not support returning a value from main. + + Valid values : + 0 - main returns an int, and return value will be 0. + 1 - platform does not support returning a value from main +*/ +#ifndef MAIN_HAS_NORETURN +#define MAIN_HAS_NORETURN 1 +#endif + +/* Variable : default_num_contexts + Not used for this simple port, must cintain the value 1. +*/ +extern ee_u32 default_num_contexts; + +typedef struct CORE_PORTABLE_S { + ee_u8 portable_id; +} core_portable; + +/* target specific init/fini */ +void portable_init(core_portable *p, int *argc, char *argv[]); +void portable_fini(core_portable *p); + +#if !defined(PROFILE_RUN) && !defined(PERFORMANCE_RUN) && !defined(VALIDATION_RUN) +#if (TOTAL_DATA_SIZE==1200) +#define PROFILE_RUN 1 +#elif (TOTAL_DATA_SIZE==2000) +#define PERFORMANCE_RUN 1 +#else +#define VALIDATION_RUN 1 +#endif +#endif + +#endif /* CORE_PORTME_H */ + + +#if HAS_STDIO +#include +#endif +#if HAS_PRINTF +#ifndef ee_printf +#define ee_printf printf +#endif +#endif + +/* Actual benchmark execution in iterate */ +void *iterate(void *pres); + +/* Typedef: secs_ret + For machines that have floating point support, get number of seconds as a double. + Otherwise an unsigned int. +*/ +#if HAS_FLOAT +typedef double secs_ret; +#else +typedef ee_u32 secs_ret; +#endif + +#if MAIN_HAS_NORETURN +#define MAIN_RETURN_VAL +#define MAIN_RETURN_TYPE void +#else +#define MAIN_RETURN_VAL 0 +#define MAIN_RETURN_TYPE int +#endif + +void start_time(void); +void stop_time(void); +CORE_TICKS get_time(void); +secs_ret time_in_secs(CORE_TICKS ticks); + +/* Misc useful functions */ +ee_u16 crcu8(ee_u8 data, ee_u16 crc); +ee_u16 crc16(ee_s16 newval, ee_u16 crc); +ee_u16 crcu16(ee_u16 newval, ee_u16 crc); +ee_u16 crcu32(ee_u32 newval, ee_u16 crc); +ee_u8 check_data_types(); +void *portable_malloc(ee_size_t size); +void portable_free(void *p); +ee_s32 parseval(char *valstring); + +/* Algorithm IDS */ +#define ID_LIST (1<<0) +#define ID_MATRIX (1<<1) +#define ID_STATE (1<<2) +#define ALL_ALGORITHMS_MASK (ID_LIST|ID_MATRIX|ID_STATE) +#define NUM_ALGORITHMS 3 + +/* list data structures */ +typedef struct list_data_s { + ee_s16 data16; + ee_s16 idx; +} list_data; + +typedef struct list_head_s { + struct list_head_s *next; + struct list_data_s *info; +} list_head; + + +/*matrix benchmark related stuff */ +#define MATDAT_INT 1 +#if MATDAT_INT +typedef ee_s16 MATDAT; +typedef ee_s32 MATRES; +#else +typedef ee_f16 MATDAT; +typedef ee_f32 MATRES; +#endif + +typedef struct MAT_PARAMS_S { + int N; + MATDAT *A; + MATDAT *B; + MATRES *C; +} mat_params; + +/* state machine related stuff */ +/* List of all the possible states for the FSM */ +typedef enum CORE_STATE { + CORE_START=0, + CORE_INVALID, + CORE_S1, + CORE_S2, + CORE_INT, + CORE_FLOAT, + CORE_EXPONENT, + CORE_SCIENTIFIC, + NUM_CORE_STATES +} core_state_e ; + + +/* Helper structure to hold results */ +typedef struct RESULTS_S { + /* inputs */ + ee_s16 seed1; /* Initializing seed */ + ee_s16 seed2; /* Initializing seed */ + ee_s16 seed3; /* Initializing seed */ + void *memblock[4]; /* Pointer to safe memory location */ + ee_u32 size; /* Size of the data */ + ee_u32 iterations; /* Number of iterations to execute */ + ee_u32 execs; /* Bitmask of operations to execute */ + struct list_head_s *list; + mat_params mat; + /* outputs */ + ee_u16 crc; + ee_u16 crclist; + ee_u16 crcmatrix; + ee_u16 crcstate; + ee_s16 err; + /* ultithread specific */ + core_portable port; +} core_results; + +/* Multicore execution handling */ +#if (MULTITHREAD>1) +ee_u8 core_start_parallel(core_results *res); +ee_u8 core_stop_parallel(core_results *res); +#endif + +/* list benchmark functions */ +list_head *core_list_init(ee_u32 blksize, list_head *memblock, ee_s16 seed); +ee_u16 core_bench_list(core_results *res, ee_s16 finder_idx); + +/* state benchmark functions */ +void core_init_state(ee_u32 size, ee_s16 seed, ee_u8 *p); +ee_u16 core_bench_state(ee_u32 blksize, ee_u8 *memblock, + ee_s16 seed1, ee_s16 seed2, ee_s16 step, ee_u16 crc); + +/* matrix benchmark functions */ +ee_u32 core_init_matrix(ee_u32 blksize, void *memblk, ee_s32 seed, mat_params *p); +ee_u16 core_bench_matrix(mat_params *p, ee_s16 seed, ee_u16 crc); + + + + + +/* +Topic: Description + Benchmark using a linked list. + + Linked list is a common data structure used in many applications. + + For our purposes, this will excercise the memory units of the processor. + In particular, usage of the list pointers to find and alter data. + + We are not using Malloc since some platforms do not support this library. + + Instead, the memory block being passed in is used to create a list, + and the benchmark takes care not to add more items then can be + accomodated by the memory block. The porting layer will make sure + that we have a valid memory block. + + All operations are done in place, without using any extra memory. + + The list itself contains list pointers and pointers to data items. + Data items contain the following: + + idx - An index that captures the initial order of the list. + data - Variable data initialized based on the input parameters. The 16b are divided as follows: + o Upper 8b are backup of original data. + o Bit 7 indicates if the lower 7 bits are to be used as is or calculated. + o Bits 0-2 indicate type of operation to perform to get a 7b value. + o Bits 3-6 provide input for the operation. + +*/ + +/* local functions */ + +list_head *core_list_find(list_head *list,list_data *info); +list_head *core_list_reverse(list_head *list); +list_head *core_list_remove(list_head *item); +list_head *core_list_undo_remove(list_head *item_removed, list_head *item_modified); +list_head *core_list_insert_new(list_head *insert_point + , list_data *info, list_head **memblock, list_data **datablock + , list_head *memblock_end, list_data *datablock_end); +typedef ee_s32(*list_cmp)(list_data *a, list_data *b, core_results *res); +list_head *core_list_mergesort(list_head *list, list_cmp cmp, core_results *res); + +ee_s16 calc_func(ee_s16 *pdata, core_results *res) { + ee_s16 data=*pdata; + ee_s16 retval; + ee_u8 optype=(data>>7) & 1; /* bit 7 indicates if the function result has been cached */ + if (optype) /* if cached, use cache */ + return (data & 0x007f); + else { /* otherwise calculate and cache the result */ + ee_s16 flag=data & 0x7; /* bits 0-2 is type of function to perform */ + ee_s16 dtype=((data>>3) & 0xf); /* bits 3-6 is specific data for the operation */ + dtype |= dtype << 4; /* replicate the lower 4 bits to get an 8b value */ + switch (flag) { + case 0: + if (dtype<0x22) /* set min period for bit corruption */ + dtype=0x22; + retval=core_bench_state(res->size,res->memblock[3],res->seed1,res->seed2,dtype,res->crc); + if (res->crcstate==0) + res->crcstate=retval; + break; + case 1: + retval=core_bench_matrix(&(res->mat),dtype,res->crc); + if (res->crcmatrix==0) + res->crcmatrix=retval; + break; + default: + retval=data; + break; + } + res->crc=crcu16(retval,res->crc); + retval &= 0x007f; + *pdata = (data & 0xff00) | 0x0080 | retval; /* cache the result */ + return retval; + } +} +/* Function: cmp_complex + Compare the data item in a list cell. + + Can be used by mergesort. +*/ +ee_s32 cmp_complex(list_data *a, list_data *b, core_results *res) { + ee_s16 val1=calc_func(&(a->data16),res); + ee_s16 val2=calc_func(&(b->data16),res); + return val1 - val2; +} + +/* Function: cmp_idx + Compare the idx item in a list cell, and regen the data. + + Can be used by mergesort. +*/ +ee_s32 cmp_idx(list_data *a, list_data *b, core_results *res) { + if (res==NULL) { + a->data16 = (a->data16 & 0xff00) | (0x00ff & (a->data16>>8)); + b->data16 = (b->data16 & 0xff00) | (0x00ff & (b->data16>>8)); + } + return a->idx - b->idx; +} + +void copy_info(list_data *to,list_data *from) { + to->data16=from->data16; + to->idx=from->idx; +} + +/* Benchmark for linked list: + - Try to find multiple data items. + - List sort + - Operate on data from list (crc) + - Single remove/reinsert + * At the end of this function, the list is back to original state +*/ +ee_u16 core_bench_list(core_results *res, ee_s16 finder_idx) { + ee_u16 retval=0; + ee_u16 found=0,missed=0; + list_head *list=res->list; + ee_s16 find_num=res->seed3; + list_head *this_find; + list_head *finder, *remover; + list_data info; + ee_s16 i; + + info.idx=finder_idx; + /* find values in the list, and change the list each time (reverse and cache if value found) */ + for (i=0; inext->info->data16 >> 8) & 1; + } + else { + found++; + if (this_find->info->data16 & 0x1) /* use found value */ + retval+=(this_find->info->data16 >> 9) & 1; + /* and cache next item at the head of the list (if any) */ + if (this_find->next != NULL) { + finder = this_find->next; + this_find->next = finder->next; + finder->next=list->next; + list->next=finder; + } + } + if (info.idx>=0) + info.idx++; +#if CORE_DEBUG + ee_printf("List find %d: [%d,%d,%d]\n",i,retval,missed,found); +#endif + } + retval+=found*4-missed; + /* sort the list by data content and remove one item*/ + if (finder_idx>0) + list=core_list_mergesort(list,cmp_complex,res); + remover=core_list_remove(list->next); + /* CRC data content of list from location of index N forward, and then undo remove */ + finder=core_list_find(list,&info); + if (!finder) + finder=list->next; + while (finder) { + retval=crc16(list->info->data16,retval); + finder=finder->next; + } +#if CORE_DEBUG + ee_printf("List sort 1: %04x\n",retval); +#endif + remover=core_list_undo_remove(remover,list->next); + /* sort the list by index, in effect returning the list to original state */ + list=core_list_mergesort(list,cmp_idx,NULL); + /* CRC data content of list */ + finder=list->next; + while (finder) { + retval=crc16(list->info->data16,retval); + finder=finder->next; + } +#if CORE_DEBUG + ee_printf("List sort 2: %04x\n",retval); +#endif + return retval; +} +/* Function: core_list_init + Initialize list with data. + + Parameters: + blksize - Size of memory to be initialized. + memblock - Pointer to memory block. + seed - Actual values chosen depend on the seed parameter. + The seed parameter MUST be supplied from a source that cannot be determined at compile time + + Returns: + Pointer to the head of the list. + +*/ +list_head *core_list_init(ee_u32 blksize, list_head *memblock, ee_s16 seed) { + /* calculated pointers for the list */ + ee_u32 per_item=16+sizeof(struct list_data_s); + ee_u32 size=(blksize/per_item)-2; /* to accomodate systems with 64b pointers, and make sure same code is executed, set max list elements */ + list_head *memblock_end=memblock+size; + list_data *datablock=(list_data *)(memblock_end); + list_data *datablock_end=datablock+size; + /* some useful variables */ + ee_u32 i; + list_head *finder,*list=memblock; + list_data info; + + /* create a fake items for the list head and tail */ + list->next=NULL; + list->info=datablock; + list->info->idx=0x0000; + list->info->data16=(ee_s16)0x8080; + memblock++; + datablock++; + info.idx=0x7fff; + info.data16=(ee_s16)0xffff; + core_list_insert_new(list,&info,&memblock,&datablock,memblock_end,datablock_end); + + /* then insert size items */ + for (i=0; inext; + i=1; + while (finder->next!=NULL) { + if (iinfo->idx=i++; + else { + ee_u16 pat=(ee_u16)(i++ ^ seed); /* get a pseudo random number */ + finder->info->idx=0x3fff & (((i & 0x07) << 8) | pat); /* make sure the mixed items end up after the ones in sequence */ + } + finder=finder->next; + } + list = core_list_mergesort(list,cmp_idx,NULL); +#if CORE_DEBUG + ee_printf("Initialized list:\n"); + finder=list; + while (finder) { + ee_printf("[%04x,%04x]",finder->info->idx,(ee_u16)finder->info->data16); + finder=finder->next; + } + ee_printf("\n"); +#endif + return list; +} + +/* Function: core_list_insert + Insert an item to the list + + Parameters: + insert_point - where to insert the item. + info - data for the cell. + memblock - pointer for the list header + datablock - pointer for the list data + memblock_end - end of region for list headers + datablock_end - end of region for list data + + Returns: + Pointer to new item. +*/ +list_head *core_list_insert_new(list_head *insert_point, list_data *info, list_head **memblock, list_data **datablock + , list_head *memblock_end, list_data *datablock_end) { + list_head *newitem; + + if ((*memblock+1) >= memblock_end) + return NULL; + if ((*datablock+1) >= datablock_end) + return NULL; + + newitem=*memblock; + (*memblock)++; + newitem->next=insert_point->next; + insert_point->next=newitem; + + newitem->info=*datablock; + (*datablock)++; + copy_info(newitem->info,info); + + return newitem; +} + +/* Function: core_list_remove + Remove an item from the list. + + Operation: + For a singly linked list, remove by copying the data from the next item + over to the current cell, and unlinking the next item. + + Note: + since there is always a fake item at the end of the list, no need to check for NULL. + + Returns: + Removed item. +*/ +list_head *core_list_remove(list_head *item) { + list_data *tmp; + list_head *ret=item->next; + /* swap data pointers */ + tmp=item->info; + item->info=ret->info; + ret->info=tmp; + /* and eliminate item */ + item->next=item->next->next; + ret->next=NULL; + return ret; +} + +/* Function: core_list_undo_remove + Undo a remove operation. + + Operation: + Since we want each iteration of the benchmark to be exactly the same, + we need to be able to undo a remove. + Link the removed item back into the list, and switch the info items. + + Parameters: + item_removed - Return value from the + item_modified - List item that was modified during + + Returns: + The item that was linked back to the list. + +*/ +list_head *core_list_undo_remove(list_head *item_removed, list_head *item_modified) { + list_data *tmp; + /* swap data pointers */ + tmp=item_removed->info; + item_removed->info=item_modified->info; + item_modified->info=tmp; + /* and insert item */ + item_removed->next=item_modified->next; + item_modified->next=item_removed; + return item_removed; +} + +/* Function: core_list_find + Find an item in the list + + Operation: + Find an item by idx (if not 0) or specific data value + + Parameters: + list - list head + info - idx or data to find + + Returns: + Found item, or NULL if not found. +*/ +list_head *core_list_find(list_head *list,list_data *info) { + if (info->idx>=0) { + while (list && (list->info->idx != info->idx)) + list=list->next; + return list; + } else { + while (list && ((list->info->data16 & 0xff) != info->data16)) + list=list->next; + return list; + } +} +/* Function: core_list_reverse + Reverse a list + + Operation: + Rearrange the pointers so the list is reversed. + + Parameters: + list - list head + info - idx or data to find + + Returns: + Found item, or NULL if not found. +*/ + +list_head *core_list_reverse(list_head *list) { + list_head *next=NULL, *tmp; + while (list) { + tmp=list->next; + list->next=next; + next=list; + list=tmp; + } + return next; +} +/* Function: core_list_mergesort + Sort the list in place without recursion. + + Description: + Use mergesort, as for linked list this is a realistic solution. + Also, since this is aimed at embedded, care was taken to use iterative rather then recursive algorithm. + The sort can either return the list to original order (by idx) , + or use the data item to invoke other other algorithms and change the order of the list. + + Parameters: + list - list to be sorted. + cmp - cmp function to use + + Returns: + New head of the list. + + Note: + We have a special header for the list that will always be first, + but the algorithm could theoretically modify where the list starts. + + */ +list_head *core_list_mergesort(list_head *list, list_cmp cmp, core_results *res) { + list_head *p, *q, *e, *tail; + ee_s32 insize, nmerges, psize, qsize, i; + + insize = 1; + + while (1) { + p = list; + list = NULL; + tail = NULL; + + nmerges = 0; /* count number of merges we do in this pass */ + + while (p) { + nmerges++; /* there exists a merge to be done */ + /* step `insize' places along from p */ + q = p; + psize = 0; + for (i = 0; i < insize; i++) { + psize++; + q = q->next; + if (!q) break; + } + + /* if q hasn't fallen off end, we have two lists to merge */ + qsize = insize; + + /* now we have two lists; merge them */ + while (psize > 0 || (qsize > 0 && q)) { + + /* decide whether next element of merge comes from p or q */ + if (psize == 0) { + /* p is empty; e must come from q. */ + e = q; q = q->next; qsize--; + } else if (qsize == 0 || !q) { + /* q is empty; e must come from p. */ + e = p; p = p->next; psize--; + } else if (cmp(p->info,q->info,res) <= 0) { + /* First element of p is lower (or same); e must come from p. */ + e = p; p = p->next; psize--; + } else { + /* First element of q is lower; e must come from q. */ + e = q; q = q->next; qsize--; + } + + /* add the next element to the merged list */ + if (tail) { + tail->next = e; + } else { + list = e; + } + tail = e; + } + + /* now p has stepped `insize' places along, and q has too */ + p = q; + } + + tail->next = NULL; + + /* If we have done only one merge, we're finished. */ + if (nmerges <= 1) /* allow for nmerges==0, the empty list case */ + return list; + + /* Otherwise repeat, merging lists twice the size */ + insize *= 2; + } +#if COMPILER_REQUIRES_SORT_RETURN + return list; +#endif +} +/* +Author : Shay Gal-On, EEMBC + +This file is part of EEMBC(R) and CoreMark(TM), which are Copyright (C) 2009 +All rights reserved. + +EEMBC CoreMark Software is a product of EEMBC and is provided under the terms of the +CoreMark License that is distributed with the official EEMBC COREMARK Software release. +If you received this EEMBC CoreMark Software without the accompanying CoreMark License, +you must discontinue use and download the official release from www.coremark.org. + +Also, if you are publicly displaying scores generated from the EEMBC CoreMark software, +make sure that you are in compliance with Run and Reporting rules specified in the accompanying readme.txt file. + +EEMBC +4354 Town Center Blvd. Suite 114-200 +El Dorado Hills, CA, 95762 +*/ +/* File: core_main.c + This file contains the framework to acquire a block of memory, seed initial parameters, tun t he benchmark and report the results. +*/ +//#include "coremark.h" + +/* Function: iterate + Run the benchmark for a specified number of iterations. + + Operation: + For each type of benchmarked algorithm: + a - Initialize the data block for the algorithm. + b - Execute the algorithm N times. + + Returns: + NULL. +*/ +static ee_u16 list_known_crc[] = {(ee_u16)0xd4b0,(ee_u16)0x3340,(ee_u16)0x6a79,(ee_u16)0xe714,(ee_u16)0xe3c1}; +static ee_u16 matrix_known_crc[] = {(ee_u16)0xbe52,(ee_u16)0x1199,(ee_u16)0x5608,(ee_u16)0x1fd7,(ee_u16)0x0747}; +static ee_u16 state_known_crc[] = {(ee_u16)0x5e47,(ee_u16)0x39bf,(ee_u16)0xe5a4,(ee_u16)0x8e3a,(ee_u16)0x8d84}; +void *iterate(void *pres) { + ee_u32 i; + ee_u16 crc; + core_results *res=(core_results *)pres; + ee_u32 iterations=res->iterations; + res->crc=0; + res->crclist=0; + res->crcmatrix=0; + res->crcstate=0; + + for (i=0; icrc=crcu16(crc,res->crc); + crc=core_bench_list(res,-1); + res->crc=crcu16(crc,res->crc); + if (i==0) res->crclist=res->crc; + } + return NULL; +} + +#if (SEED_METHOD==SEED_ARG) +ee_s32 get_seed_args(int i, int argc, char *argv[]); +#define get_seed(x) (ee_s16)get_seed_args(x,argc,argv) +#define get_seed_32(x) get_seed_args(x,argc,argv) +#else /* via function or volatile */ +ee_s32 get_seed_32(int i); +#define get_seed(x) (ee_s16)get_seed_32(x) +#endif + +#if (MEM_METHOD==MEM_STATIC) +ee_u8 static_memblk[TOTAL_DATA_SIZE]; +#endif +char *mem_name[3] = {"Static","Heap","Stack"}; +/* Function: main + Main entry routine for the benchmark. + This function is responsible for the following steps: + + 1 - Initialize input seeds from a source that cannot be determined at compile time. + 2 - Initialize memory block for use. + 3 - Run and time the benchmark. + 4 - Report results, testing the validity of the output if the seeds are known. + + Arguments: + 1 - first seed : Any value + 2 - second seed : Must be identical to first for iterations to be identical + 3 - third seed : Any value, should be at least an order of magnitude less then the input size, but bigger then 32. + 4 - Iterations : Special, if set to 0, iterations will be automatically determined such that the benchmark will run between 10 to 100 secs + +*/ + +#if MAIN_HAS_NOARGC +MAIN_RETURN_TYPE main(void) { + int argc=0; + char *argv[1]; +#else +MAIN_RETURN_TYPE main(int argc, char *argv[]) { +#endif + ee_u16 i,j=0,num_algorithms=0; + ee_s16 known_id=-1,total_errors=0; + ee_u16 seedcrc=0; + CORE_TICKS total_time; + core_results results[MULTITHREAD]; +#if (MEM_METHOD==MEM_STACK) + ee_u8 stack_memblock[TOTAL_DATA_SIZE*MULTITHREAD]; +#endif + /* first call any initializations needed */ + portable_init(&(results[0].port), &argc, argv); + /* First some checks to make sure benchmark will run ok */ + if (sizeof(struct list_head_s)>128) { + ee_printf("list_head structure too big for comparable data!\n"); + return MAIN_RETURN_VAL; + } + results[0].seed1=get_seed(1); + results[0].seed2=get_seed(2); + results[0].seed3=get_seed(3); + results[0].iterations=get_seed_32(4); +#if CORE_DEBUG + results[0].iterations=1; +#endif + results[0].execs=get_seed_32(5); + if (results[0].execs==0) { /* if not supplied, execute all algorithms */ + results[0].execs=ALL_ALGORITHMS_MASK; + } + /* put in some default values based on one seed only for easy testing */ + if ((results[0].seed1==0) && (results[0].seed2==0) && (results[0].seed3==0)) { /* validation run */ + results[0].seed1=0; + results[0].seed2=0; + results[0].seed3=0x66; + } + if ((results[0].seed1==1) && (results[0].seed2==0) && (results[0].seed3==0)) { /* perfromance run */ + results[0].seed1=0x3415; + results[0].seed2=0x3415; + results[0].seed3=0x66; + } +#if (MEM_METHOD==MEM_STATIC) + results[0].memblock[0]=(void *)static_memblk; + results[0].size=TOTAL_DATA_SIZE; + results[0].err=0; + #if (MULTITHREAD>1) + #error "Cannot use a static data area with multiple contexts!" + #endif +#elif (MEM_METHOD==MEM_MALLOC) + for (i=0 ; i1) + if (default_num_contexts>MULTITHREAD) { + default_num_contexts=MULTITHREAD; + } + for (i=0 ; i=0) { + for (i=0 ; i 0) + ee_printf("Iterations/Sec : %f\n",default_num_contexts*results[0].iterations/time_in_secs(total_time)); +#else + ee_printf("Total time (secs): %d\n",time_in_secs(total_time)); + if (time_in_secs(total_time) > 0) +// ee_printf("Iterations/Sec : %d\n",default_num_contexts*results[0].iterations/time_in_secs(total_time)); + ee_printf("Iterat/Sec/MHz : %d.%d\n",1000*default_num_contexts*results[0].iterations/time_in_secs(total_time), + 100000*default_num_contexts*results[0].iterations/time_in_secs(total_time) % 100); +#endif + if (time_in_secs(total_time) < 10) { + ee_printf("ERROR! Must execute for at least 10 secs for a valid result!\n"); + total_errors++; + } + + ee_printf("Iterations : %u\n",(ee_u32)default_num_contexts*results[0].iterations); + ee_printf("Compiler version : %s\n",COMPILER_VERSION); + ee_printf("Compiler flags : %s\n",COMPILER_FLAGS); +#if (MULTITHREAD>1) + ee_printf("Parallel %s : %d\n",PARALLEL_METHOD,default_num_contexts); +#endif + ee_printf("Memory location : %s\n",MEM_LOCATION); + /* output for verification */ + ee_printf("seedcrc : 0x%04x\n",seedcrc); + if (results[0].execs & ID_LIST) + for (i=0 ; i1) + ee_printf(" / %d:%s",default_num_contexts,PARALLEL_METHOD); +#endif + ee_printf("\n"); + } +#endif + } + if (total_errors>0) + ee_printf("Errors detected\n"); + if (total_errors<0) + ee_printf("Cannot validate operation for these seed values, please compare with results on a known platform.\n"); + +#if (MEM_METHOD==MEM_MALLOC) + for (i=0 ; i>(from)) & (~(0xffffffff << (to)))) + +#if CORE_DEBUG +void printmat(MATDAT *A, ee_u32 N, char *name) { + ee_u32 i,j; + ee_printf("Matrix %s [%dx%d]:\n",name,N,N); + for (i=0; i N times, + changing the matrix values slightly by a constant amount each time. +*/ +ee_u16 core_bench_matrix(mat_params *p, ee_s16 seed, ee_u16 crc) { + ee_u32 N=p->N; + MATRES *C=p->C; + MATDAT *A=p->A; + MATDAT *B=p->B; + MATDAT val=(MATDAT)seed; + + crc=crc16(matrix_test(N,C,A,B,val),crc); + + return crc; +} + +/* Function: matrix_test + Perform matrix manipulation. + + Parameters: + N - Dimensions of the matrix. + C - memory for result matrix. + A - input matrix + B - operator matrix (not changed during operations) + + Returns: + A CRC value that captures all results calculated in the function. + In particular, crc of the value calculated on the result matrix + after each step by . + + Operation: + + 1 - Add a constant value to all elements of a matrix. + 2 - Multiply a matrix by a constant. + 3 - Multiply a matrix by a vector. + 4 - Multiply a matrix by a matrix. + 5 - Add a constant value to all elements of a matrix. + + After the last step, matrix A is back to original contents. +*/ +ee_s16 matrix_test(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B, MATDAT val) { + ee_u16 crc=0; + MATDAT clipval=matrix_big(val); + + matrix_add_const(N,A,val); /* make sure data changes */ +#if CORE_DEBUG + printmat(A,N,"matrix_add_const"); +#endif + matrix_mul_const(N,C,A,val); + crc=crc16(matrix_sum(N,C,clipval),crc); +#if CORE_DEBUG + printmatC(C,N,"matrix_mul_const"); +#endif + matrix_mul_vect(N,C,A,B); + crc=crc16(matrix_sum(N,C,clipval),crc); +#if CORE_DEBUG + printmatC(C,N,"matrix_mul_vect"); +#endif + matrix_mul_matrix(N,C,A,B); + crc=crc16(matrix_sum(N,C,clipval),crc); +#if CORE_DEBUG + printmatC(C,N,"matrix_mul_matrix"); +#endif + matrix_mul_matrix_bitextract(N,C,A,B); + crc=crc16(matrix_sum(N,C,clipval),crc); +#if CORE_DEBUG + printmatC(C,N,"matrix_mul_matrix_bitextract"); +#endif + + matrix_add_const(N,A,-val); /* return matrix to initial value */ + return crc; +} + +/* Function : matrix_init + Initialize the memory block for matrix benchmarking. + + Parameters: + blksize - Size of memory to be initialized. + memblk - Pointer to memory block. + seed - Actual values chosen depend on the seed parameter. + p - pointers to containing initialized matrixes. + + Returns: + Matrix dimensions. + + Note: + The seed parameter MUST be supplied from a source that cannot be determined at compile time +*/ +ee_u32 core_init_matrix(ee_u32 blksize, void *memblk, ee_s32 seed, mat_params *p) { + ee_u32 N=0; + MATDAT *A; + MATDAT *B; + ee_s32 order=1; + MATDAT val; + ee_u32 i=0,j=0; + if (seed==0) + seed=1; + while (jA=A; + p->B=B; + p->C=(MATRES *)align_mem(B+N*N); + p->N=N; +#if CORE_DEBUG + printmat(A,N,"A"); + printmat(B,N,"B"); +#endif + return N; +} + +/* Function: matrix_sum + Calculate a function that depends on the values of elements in the matrix. + + For each element, accumulate into a temporary variable. + + As long as this value is under the parameter clipval, + add 1 to the result if the element is bigger then the previous. + + Otherwise, reset the accumulator and add 10 to the result. +*/ +ee_s16 matrix_sum(ee_u32 N, MATRES *C, MATDAT clipval) { + MATRES tmp=0,prev=0,cur=0; + ee_s16 ret=0; + ee_u32 i,j; + for (i=0; iclipval) { + ret+=10; + tmp=0; + } else { + ret += (cur>prev) ? 1 : 0; + } + prev=cur; + } + } + return ret; +} + +/* Function: matrix_mul_const + Multiply a matrix by a constant. + This could be used as a scaler for instance. +*/ +void matrix_mul_const(ee_u32 N, MATRES *C, MATDAT *A, MATDAT val) { + ee_u32 i,j; + for (i=0; i0) { + for(i=0;i>3) & 0x3]; + next=4; + break; + case 3: /* float */ + case 4: /* float */ + buf=floatpat[(seed>>3) & 0x3]; + next=8; + break; + case 5: /* scientific */ + case 6: /* scientific */ + buf=scipat[(seed>>3) & 0x3]; + next=8; + break; + case 7: /* invalid */ + buf=errpat[(seed>>3) & 0x3]; + next=8; + break; + default: /* Never happen, just to make some compilers happy */ + break; + } + } + size++; + while (total='0') & (c<='9')) ? 1 : 0; + return retval; +} + +/* Function: core_state_transition + Actual state machine. + + The state machine will continue scanning until either: + 1 - an invalid input is detcted. + 2 - a valid number has been detected. + + The input pointer is updated to point to the end of the token, and the end state is returned (either specific format determined or invalid). +*/ + +enum CORE_STATE core_state_transition( ee_u8 **instr , ee_u32 *transition_count) { + ee_u8 *str=*instr; + ee_u8 NEXT_SYMBOL; + enum CORE_STATE state=CORE_START; + for( ; *str && state != CORE_INVALID; str++ ) { + NEXT_SYMBOL = *str; + if (NEXT_SYMBOL==',') /* end of this input */ { + str++; + break; + } + switch(state) { + case CORE_START: + if(ee_isdigit(NEXT_SYMBOL)) { + state = CORE_INT; + } + else if( NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-' ) { + state = CORE_S1; + } + else if( NEXT_SYMBOL == '.' ) { + state = CORE_FLOAT; + } + else { + state = CORE_INVALID; + transition_count[CORE_INVALID]++; + } + transition_count[CORE_START]++; + break; + case CORE_S1: + if(ee_isdigit(NEXT_SYMBOL)) { + state = CORE_INT; + transition_count[CORE_S1]++; + } + else if( NEXT_SYMBOL == '.' ) { + state = CORE_FLOAT; + transition_count[CORE_S1]++; + } + else { + state = CORE_INVALID; + transition_count[CORE_S1]++; + } + break; + case CORE_INT: + if( NEXT_SYMBOL == '.' ) { + state = CORE_FLOAT; + transition_count[CORE_INT]++; + } + else if(!ee_isdigit(NEXT_SYMBOL)) { + state = CORE_INVALID; + transition_count[CORE_INT]++; + } + break; + case CORE_FLOAT: + if( NEXT_SYMBOL == 'E' || NEXT_SYMBOL == 'e' ) { + state = CORE_S2; + transition_count[CORE_FLOAT]++; + } + else if(!ee_isdigit(NEXT_SYMBOL)) { + state = CORE_INVALID; + transition_count[CORE_FLOAT]++; + } + break; + case CORE_S2: + if( NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-' ) { + state = CORE_EXPONENT; + transition_count[CORE_S2]++; + } + else { + state = CORE_INVALID; + transition_count[CORE_S2]++; + } + break; + case CORE_EXPONENT: + if(ee_isdigit(NEXT_SYMBOL)) { + state = CORE_SCIENTIFIC; + transition_count[CORE_EXPONENT]++; + } + else { + state = CORE_INVALID; + transition_count[CORE_EXPONENT]++; + } + break; + case CORE_SCIENTIFIC: + if(!ee_isdigit(NEXT_SYMBOL)) { + state = CORE_INVALID; + transition_count[CORE_INVALID]++; + } + break; + default: + break; + } + } + *instr=str; + return state; +} +/* +Author : Shay Gal-On, EEMBC + +This file is part of EEMBC(R) and CoreMark(TM), which are Copyright (C) 2009 +All rights reserved. + +EEMBC CoreMark Software is a product of EEMBC and is provided under the terms of the +CoreMark License that is distributed with the official EEMBC COREMARK Software release. +If you received this EEMBC CoreMark Software without the accompanying CoreMark License, +you must discontinue use and download the official release from www.coremark.org. + +Also, if you are publicly displaying scores generated from the EEMBC CoreMark software, +make sure that you are in compliance with Run and Reporting rules specified in the accompanying readme.txt file. + +EEMBC +4354 Town Center Blvd. Suite 114-200 +El Dorado Hills, CA, 95762 +*/ +//#include "coremark.h" +/* Function: get_seed + Get a values that cannot be determined at compile time. + + Since different embedded systems and compilers are used, 3 different methods are provided: + 1 - Using a volatile variable. This method is only valid if the compiler is forced to generate code that + reads the value of a volatile variable from memory at run time. + Please note, if using this method, you would need to modify core_portme.c to generate training profile. + 2 - Command line arguments. This is the preferred method if command line arguments are supported. + 3 - System function. If none of the first 2 methods is available on the platform, + a system function which is not a stub can be used. + + e.g. read the value on GPIO pins connected to switches, or invoke special simulator functions. +*/ +#if (SEED_METHOD==SEED_VOLATILE) + extern volatile ee_s32 seed1_volatile; + extern volatile ee_s32 seed2_volatile; + extern volatile ee_s32 seed3_volatile; + extern volatile ee_s32 seed4_volatile; + extern volatile ee_s32 seed5_volatile; + ee_s32 get_seed_32(int i) { + ee_s32 retval; + switch (i) { + case 1: + retval=seed1_volatile; + break; + case 2: + retval=seed2_volatile; + break; + case 3: + retval=seed3_volatile; + break; + case 4: + retval=seed4_volatile; + break; + case 5: + retval=seed5_volatile; + break; + default: + retval=0; + break; + } + return retval; + } +#elif (SEED_METHOD==SEED_ARG) +ee_s32 parseval(char *valstring) { + ee_s32 retval=0; + ee_s32 neg=1; + int hexmode=0; + if (*valstring == '-') { + neg=-1; + valstring++; + } + if ((valstring[0] == '0') && (valstring[1] == 'x')) { + hexmode=1; + valstring+=2; + } + /* first look for digits */ + if (hexmode) { + while (((*valstring >= '0') && (*valstring <= '9')) || ((*valstring >= 'a') && (*valstring <= 'f'))) { + ee_s32 digit=*valstring-'0'; + if (digit>9) + digit=10+*valstring-'a'; + retval*=16; + retval+=digit; + valstring++; + } + } else { + while ((*valstring >= '0') && (*valstring <= '9')) { + ee_s32 digit=*valstring-'0'; + retval*=10; + retval+=digit; + valstring++; + } + } + /* now add qualifiers */ + if (*valstring=='K') + retval*=1024; + if (*valstring=='M') + retval*=1024*1024; + + retval*=neg; + return retval; +} + +ee_s32 get_seed_args(int i, int argc, char *argv[]) { + if (argc>i) + return parseval(argv[i]); + return 0; +} + +#elif (SEED_METHOD==SEED_FUNC) +/* If using OS based function, you must define and implement the functions below in core_portme.h and core_portme.c ! */ +ee_s32 get_seed_32(int i) { + ee_s32 retval; + switch (i) { + case 1: + retval=portme_sys1(); + break; + case 2: + retval=portme_sys2(); + break; + case 3: + retval=portme_sys3(); + break; + case 4: + retval=portme_sys4(); + break; + case 5: + retval=portme_sys5(); + break; + default: + retval=0; + break; + } + return retval; +} +#endif + +/* Function: crc* + Service functions to calculate 16b CRC code. + +*/ +ee_u16 crcu8(ee_u8 data, ee_u16 crc ) +{ + ee_u8 i=0,x16=0,carry=0; + + for (i = 0; i < 8; i++) + { + x16 = (ee_u8)((data & 1) ^ ((ee_u8)crc & 1)); + data >>= 1; + + if (x16 == 1) + { + crc ^= 0x4002; + carry = 1; + } + else + carry = 0; + crc >>= 1; + if (carry) + crc |= 0x8000; + else + crc &= 0x7fff; + } + return crc; +} +ee_u16 crcu16(ee_u16 newval, ee_u16 crc) { + crc=crcu8( (ee_u8) (newval) ,crc); + crc=crcu8( (ee_u8) ((newval)>>8) ,crc); + return crc; +} +ee_u16 crcu32(ee_u32 newval, ee_u16 crc) { + crc=crc16((ee_s16) newval ,crc); + crc=crc16((ee_s16) (newval>>16) ,crc); + return crc; +} +ee_u16 crc16(ee_s16 newval, ee_u16 crc) { + return crcu16((ee_u16)newval, crc); +} + +ee_u8 check_data_types() { + ee_u8 retval=0; + if (sizeof(ee_u8) != 1) { + ee_printf("ERROR: ee_u8 is not an 8b datatype!\n"); + retval++; + } + if (sizeof(ee_u16) != 2) { + ee_printf("ERROR: ee_u16 is not a 16b datatype!\n"); + retval++; + } + if (sizeof(ee_s16) != 2) { + ee_printf("ERROR: ee_s16 is not a 16b datatype!\n"); + retval++; + } + if (sizeof(ee_s32) != 4) { + ee_printf("ERROR: ee_s32 is not a 32b datatype!\n"); + retval++; + } + if (sizeof(ee_u32) != 4) { + ee_printf("ERROR: ee_u32 is not a 32b datatype!\n"); + retval++; + } + if (sizeof(ee_ptr_int) != sizeof(int *)) { + ee_printf("ERROR: ee_ptr_int is not a datatype that holds an int pointer!\n"); + retval++; + } + if (retval>0) { + ee_printf("ERROR: Please modify the datatypes in core_portme.h!\n"); + } + return retval; +} +/* + File : core_portme.c +*/ +/* + Author : Shay Gal-On, EEMBC + Legal : TODO! +*/ +#include +#include +//#include "coremark.h" + +#if VALIDATION_RUN + volatile ee_s32 seed1_volatile=0x3415; + volatile ee_s32 seed2_volatile=0x3415; + volatile ee_s32 seed3_volatile=0x66; +#endif +#if PERFORMANCE_RUN + volatile ee_s32 seed1_volatile=0x0; + volatile ee_s32 seed2_volatile=0x0; + volatile ee_s32 seed3_volatile=0x66; +#endif +#if PROFILE_RUN + volatile ee_s32 seed1_volatile=0x8; + volatile ee_s32 seed2_volatile=0x8; + volatile ee_s32 seed3_volatile=0x8; +#endif + volatile ee_s32 seed4_volatile=ITERATIONS; + volatile ee_s32 seed5_volatile=0; +/* Porting : Timing functions + How to capture time and convert to seconds must be ported to whatever is supported by the platform. + e.g. Read value from on board RTC, read value from cpu clock cycles performance counter etc. + Sample implementation for standard time.h and windows.h definitions included. +*/ +/* Define : TIMER_RES_DIVIDER + Divider to trade off timer resolution and total time that can be measured. + + Use lower values to increase resolution, but make sure that overflow does not occur. + If there are issues with the return value overflowing, increase this value. + */ +//#define NSECS_PER_SEC CLOCKS_PER_SEC +#define NSECS_PER_SEC 1000000000 +#define CORETIMETYPE clock_t +//#define GETMYTIME(_t) (*_t=clock()) +#define GETMYTIME(_t) (*_t=0) +#define MYTIMEDIFF(fin,ini) ((fin)-(ini)) +#define TIMER_RES_DIVIDER 1 +#define SAMPLE_TIME_IMPLEMENTATION 1 +//#define EE_TICKS_PER_SEC (NSECS_PER_SEC / TIMER_RES_DIVIDER) + +#define EE_TICKS_PER_SEC 1000 + +/** Define Host specific (POSIX), or target specific global time variables. */ +static CORETIMETYPE start_time_val, stop_time_val; + +/* Function : start_time + This function will be called right before starting the timed portion of the benchmark. + + Implementation may be capturing a system timer (as implemented in the example code) + or zeroing some system parameters - e.g. setting the cpu clocks cycles to 0. +*/ +void start_time(void) { +uint32_t mcyclel; + asm volatile ("csrr %0,mcycle" : "=r" (mcyclel) ); + start_time_val = mcyclel; +} +/* Function : stop_time + This function will be called right after ending the timed portion of the benchmark. + + Implementation may be capturing a system timer (as implemented in the example code) + or other system parameters - e.g. reading the current value of cpu cycles counter. +*/ +void stop_time(void) { +uint32_t mcyclel; + asm volatile ("csrr %0,mcycle" : "=r" (mcyclel) ); + stop_time_val = mcyclel; +} +/* Function : get_time + Return an abstract "ticks" number that signifies time on the system. + + Actual value returned may be cpu cycles, milliseconds or any other value, + as long as it can be converted to seconds by . + This methodology is taken to accomodate any hardware or simulated platform. + The sample implementation returns millisecs by default, + and the resolution is controlled by +*/ +CORE_TICKS get_time(void) { + CORE_TICKS elapsed=(CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val)); + return elapsed; +} +/* Function : time_in_secs + Convert the value returned by get_time to seconds. + + The type is used to accomodate systems with no support for floating point. + Default implementation implemented by the EE_TICKS_PER_SEC macro above. +*/ +secs_ret time_in_secs(CORE_TICKS ticks) { + secs_ret retval=((secs_ret)ticks) / (secs_ret)EE_TICKS_PER_SEC; + return retval; +} + +ee_u32 default_num_contexts=1; + +/* Function : portable_init + Target specific initialization code + Test for some common mistakes. +*/ +void portable_init(core_portable *p, int *argc, char *argv[]) +{ + if (sizeof(ee_ptr_int) != sizeof(ee_u8 *)) { + ee_printf("ERROR! Please define ee_ptr_int to a type that holds a pointer!\n"); + } + if (sizeof(ee_u32) != 4) { + ee_printf("ERROR! Please define ee_u32 to a 32b unsigned type!\n"); + } + p->portable_id=1; +} +/* Function : portable_fini + Target specific final code +*/ +void portable_fini(core_portable *p) +{ + p->portable_id=0; +} + + +#include + +// Special address. Writing (store byte instruction) to this address +// causes the simulator to write to the console. +volatile char __whisper_console_io = 0; + + +static int +whisperPutc(char c) +{ +// __whisper_console_io = c; +// __whisper_console_io = c; + *(volatile char*)(STDOUT) = c; + return c; +} + + +static int +whisperPuts(const char* s) +{ + while (*s) + whisperPutc(*s++); + return 1; +} + + +static int +whisperPrintDecimal(int value) +{ + char buffer[20]; + int charCount = 0; + + unsigned neg = value < 0; + if (neg) + { + value = -value; + whisperPutc('-'); + } + + do + { + char c = '0' + (value % 10); + value = value / 10; + buffer[charCount++] = c; + } + while (value); + + char* p = buffer + charCount - 1; + for (unsigned i = 0; i < charCount; ++i) + whisperPutc(*p--); + + if (neg) + charCount++; + + return charCount; +} + + +static int +whisperPrintInt(int value, int base) +{ + if (base == 10) + return whisperPrintDecimal(value); + + char buffer[20]; + int charCount = 0; + + unsigned uu = value; + + if (base == 8) + { + do + { + char c = '0' + (uu & 7); + buffer[charCount++] = c; + uu >>= 3; + } + while (uu); + } + else if (base == 16) + { + do + { + int digit = uu & 0xf; + char c = digit < 10 ? '0' + digit : 'a' + digit; + buffer[charCount++] = c; + uu >>= 4; + } + while (uu); + } + else + return -1; + + char* p = buffer + charCount - 1; + for (unsigned i = 0; i < charCount; ++i) + whisperPutc(*p--); + + return charCount; +} + + +int +whisperPrintfImpl(const char* format, va_list ap) +{ + int count = 0; // Printed character count + + for (const char* fp = format; *fp; fp++) + { + if (*fp != '%') + { + whisperPutc(*fp); + ++count; + continue; + } + + ++fp; // Skip % + + if (*fp == 0) + break; + + if (*fp == '%') + { + whisperPutc('%'); + continue; + } + + if (*fp == '-') + { + fp++; // Pad right not yet implemented. + } + + while (*fp == '0') + { + fp++; // Pad zero not yet implented. + } + + if (*fp == '*') + { + int width = va_arg(ap, int); + fp++; // Width not yet implemented. + } + else + { + while (*fp >= '0' && *fp <= '9') + ++fp; // Width not yet implemented. + } + + switch (*fp) + { + case 'd': + count += whisperPrintDecimal(va_arg(ap, int)); + break; + + case 'u': + count += whisperPrintDecimal((unsigned) va_arg(ap, unsigned)); + break; + + case 'x': + case 'X': + count += whisperPrintInt(va_arg(ap, int), 16); + break; + + case 'o': + count += whisperPrintInt(va_arg(ap, int), 8); + break; + + case 'c': + whisperPutc(va_arg(ap, int)); + ++count; + break; + + case 's': + count += whisperPuts(va_arg(ap, char*)); + break; + } + } + + return count; +} + + +int +whisperPrintf(const char* format, ...) +{ + va_list ap; + + va_start(ap, format); + int code = whisperPrintfImpl(format, ap); + va_end(ap); + + return code; +} + + +int +printf(const char* format, ...) +{ + va_list ap; + + va_start(ap, format); + int code = whisperPrintfImpl(format, ap); + va_end(ap); + + return code; +} + + +void* memset(void* s, int c, size_t n) +{ + asm("mv t0, a0"); + asm("add a2, a2, a0"); // end = s + n + asm(".memset_loop: bge a0, a2, .memset_end"); + asm("sb a1, 0(a0)"); + asm("addi a0, a0, 1"); + asm("j .memset_loop"); + asm(".memset_end:"); + asm("mv a0, t0"); + asm("jr ra"); +} diff --git a/testbench/asm/cmark_iccm.ld b/testbench/asm/cmark_iccm.ld new file mode 100644 index 0000000..df96216 --- /dev/null +++ b/testbench/asm/cmark_iccm.ld @@ -0,0 +1,17 @@ + +OUTPUT_ARCH( "riscv" ) +ENTRY(_start) +MEMORY { + EXTCODE : ORIGIN = 0, LENGTH = 0x10000 + EXTDATA : ORIGIN = 0x10000, LENGTH = 0x10000 + ICCM : ORIGIN = 0xee000000, LENGTH = 0x80000 + DCCM : ORIGIN = 0xf0040000, LENGTH = 0x10000 +} +SECTIONS { + .text_init : {*(.text_init)} > EXTCODE + init_end = .; + .data.ctl : AT(0xffec) { LONG(ADDR(.text)); LONG(text_end); LONG(LOADADDR(.text)); LONG(0xf0040000); LONG(STACK)}>EXTDATA + .text : AT(init_end) { *(.text) *(.text.startup)} > ICCM + text_end = .; + .data : AT(0x10000) { *(.*data) *(.rodata*) STACK = ALIGN(16) + 0x8000;} > DCCM +} diff --git a/testbench/asm/hello_world_dccm.ld b/testbench/asm/hello_world_dccm.ld new file mode 100644 index 0000000..eea3cbe --- /dev/null +++ b/testbench/asm/hello_world_dccm.ld @@ -0,0 +1,12 @@ + +OUTPUT_ARCH( "riscv" ) +ENTRY(_start) + +SECTIONS { + .text : { *(.text*) } + _end = .; + . = 0xfff8; + .data.ctl : { LONG(0xf0040000); LONG(STACK) } + . = 0xf0040000; + .data : AT(0x10000) { *(.*data) *(.rodata*) STACK = ALIGN(16) + 0x8000;} +} diff --git a/testbench/asm/hello_world_dccm.s b/testbench/asm/hello_world_dccm.s new file mode 120000 index 0000000..3418f77 --- /dev/null +++ b/testbench/asm/hello_world_dccm.s @@ -0,0 +1 @@ +hello_world.s \ No newline at end of file diff --git a/testbench/flist b/testbench/flist new file mode 100644 index 0000000..3390243 --- /dev/null +++ b/testbench/flist @@ -0,0 +1,42 @@ +$RV_ROOT/design/swerv_wrapper.sv +$RV_ROOT/design/mem.sv +$RV_ROOT/design/pic_ctrl.sv +$RV_ROOT/design/swerv.sv +$RV_ROOT/design/dma_ctrl.sv +$RV_ROOT/design/ifu/ifu_aln_ctl.sv +$RV_ROOT/design/ifu/ifu_compress_ctl.sv +$RV_ROOT/design/ifu/ifu_ifc_ctl.sv +$RV_ROOT/design/ifu/ifu_bp_ctl.sv +$RV_ROOT/design/ifu/ifu_ic_mem.sv +$RV_ROOT/design/ifu/ifu_mem_ctl.sv +$RV_ROOT/design/ifu/ifu_iccm_mem.sv +$RV_ROOT/design/ifu/ifu.sv +$RV_ROOT/design/dec/dec_decode_ctl.sv +$RV_ROOT/design/dec/dec_gpr_ctl.sv +$RV_ROOT/design/dec/dec_ib_ctl.sv +$RV_ROOT/design/dec/dec_tlu_ctl.sv +$RV_ROOT/design/dec/dec_trigger.sv +$RV_ROOT/design/dec/dec.sv +$RV_ROOT/design/exu/exu_alu_ctl.sv +$RV_ROOT/design/exu/exu_mul_ctl.sv +$RV_ROOT/design/exu/exu_div_ctl.sv +$RV_ROOT/design/exu/exu.sv +$RV_ROOT/design/lsu/lsu.sv +$RV_ROOT/design/lsu/lsu_clkdomain.sv +$RV_ROOT/design/lsu/lsu_addrcheck.sv +$RV_ROOT/design/lsu/lsu_lsc_ctl.sv +$RV_ROOT/design/lsu/lsu_stbuf.sv +$RV_ROOT/design/lsu/lsu_bus_buffer.sv +$RV_ROOT/design/lsu/lsu_bus_intf.sv +$RV_ROOT/design/lsu/lsu_ecc.sv +$RV_ROOT/design/lsu/lsu_dccm_mem.sv +$RV_ROOT/design/lsu/lsu_dccm_ctl.sv +$RV_ROOT/design/lsu/lsu_trigger.sv +$RV_ROOT/design/dbg/dbg.sv +$RV_ROOT/design/dmi/dmi_wrapper.v +$RV_ROOT/design/dmi/dmi_jtag_to_core_sync.v +$RV_ROOT/design/dmi/rvjtag_tap.sv +-v $RV_ROOT/design/lib/beh_lib.sv +-v $RV_ROOT/design/lib/mem_lib.sv +-v $RV_ROOT/design/lib/ahb_to_axi4.sv +-v $RV_ROOT/design/lib/axi4_to_ahb.sv