From e54ddab4e2163a13e0c22ad1a032706295bf2f7f Mon Sep 17 00:00:00 2001 From: "Ruige Lee (WSL)" <295054118@whut.edu.cn> Date: Thu, 16 Jan 2025 16:34:48 +0800 Subject: [PATCH] =?UTF-8?q?=E5=86=99=E5=AE=8C=E8=BD=AF=E4=BB=B6=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E5=8A=A0gpio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 1 - tb/sw/src/SlvMain.c | 460 ++++++++++++++++++++-------------- tb/sw/src/custom_ops.S.bk | 102 -------- tb/sw/src/mstMain.S.bk | 56 ----- tb/sw/src/slvMain.S.bk | 175 ------------- tb/sw/src/slvStartup.S | 108 +++++++- tb/sw/tl2cdr/tl2cdr.c | 6 +- tb/verilator/SimTop.v | 66 ++--- tb/verilator/plusarg_reader.v | 17 ++ 9 files changed, 419 insertions(+), 572 deletions(-) delete mode 100644 tb/sw/src/custom_ops.S.bk delete mode 100644 tb/sw/src/mstMain.S.bk delete mode 100644 tb/sw/src/slvMain.S.bk create mode 100644 tb/verilator/plusarg_reader.v diff --git a/Makefile b/Makefile index a0255f9..798a512 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,6 @@ compile: cd ./rocket-chip/vsim && make verilog CONFIG=freechips.rocketchip.system.RtppConfig cp ./rocket-chip/vsim/generated-src/freechips.rocketchip.system.RtppConfig.v ./generated/Rtpp/RtppConfig.v cp ./rocket-chip/vsim/generated-src/freechips.rocketchip.system.RtppConfig.behav_srams.v ./generated/Rtpp/behav_srams.v - cp ./rocket-chip/vsim/generated-src/freechips.rocketchip.system.RtppConfig/plusarg_reader.v ./generated/Rtpp/plusarg_reader.v # sbt "test:runMain test.testModule" back: diff --git a/tb/sw/src/SlvMain.c b/tb/sw/src/SlvMain.c index 98970c7..d56ae4c 100644 --- a/tb/sw/src/SlvMain.c +++ b/tb/sw/src/SlvMain.c @@ -3,62 +3,59 @@ // #include "uart.h" // #include "gpio.h" // #include "timer.h" +#include "tl2cdr.h" - -volatile uint32_t *cdr_status = (uint32_t*)( 0x000 + 0x0 ); //read -volatile uint32_t *cdr_txLen = (uint32_t*)( 0x000 + 0x4 ); //write -volatile uint32_t *cdr_txFifo = (uint32_t*)( 0x000 + 0x8 ); //write -volatile uint32_t *cdr_direct = (uint32_t*)( 0x000 + 0xc ); //write - -volatile uint32_t *cdr_softReset = (uint32_t*)( 0x000 + 0x10 ); //write -volatile uint32_t *cdr_rxLen = (uint32_t*)( 0x000 + 0x18 ); //read -volatile uint32_t *cdr_rxFifo = (uint32_t*)( 0x000 + 0x1c ); //read - - -volatile uint32_t *WriteGpio = (uint32_t*) ( 0x400); -volatile uint32_t *ReadGpio = (uint32_t*) ( 0x400); -volatile uint32_t *ReadIsLast = (uint32_t*) ( 0x408); - - - - - - - - - - - +volatile uint32_t *plic_priority_3 = (uint32_t*)( 0xc000000U + 0X000004 * 3); +volatile uint32_t *plic_priority_4 = (uint32_t*)( 0xc000000U + 0X000004 * 4); +volatile uint32_t *plic_priority_5 = (uint32_t*)( 0xc000000U + 0X000004 * 5); +volatile uint32_t *plic_priority_6 = (uint32_t*)( 0xc000000U + 0X000004 * 6); volatile uint32_t *plic_pending_0_31 = (uint32_t*)( 0xc000000U + 0X001000 ); volatile uint32_t *plic_enable_0_31 = (uint32_t*)( 0xc000000U + 0X002000 ); + +volatile uint32_t *plic_threshold_0 = (uint32_t*)( 0xc000000U + 0X200000 ); volatile uint32_t *plic_claim = (uint32_t*)( 0xc000000U + 0X200004 ); -uint32_t flag_intTxEnd = 0; -uint32_t flag_intRxError = 0; -uint32_t flag_intRxStart = 0; -uint32_t flag_intRxEnd = 0; + +volatile uint32_t flag_intTxEnd = 0; +volatile uint32_t flag_intRxError = 0; +volatile uint32_t flag_intRxStart = 0; +volatile uint32_t flag_intRxEnd = 0; -void trap_entry(){ - if( *plic_claim == 3 ){ +void plic_handle(){ + + + // 从 PLIC 中获取中断源 ID + uint32_t claim = *plic_claim; + + + if( claim == 3 ){ flag_intTxEnd = 1; - } else if( *plic_claim == 4 ){ + } else if( claim == 4 ){ flag_intRxError = 1; - } else if( *plic_claim == 5 ){ + } else if( claim == 5 ){ flag_intRxStart = 1; - } else if( *plic_claim == 6 ){ + } else if( claim == 6 ){ flag_intRxEnd = 1; } + + // 通知 PLIC 完成中断处理 + *plic_claim = claim; return; } + -// static inline void error() { -// while(1); -// } +static inline void error() { + while(1); +} + + + + @@ -69,52 +66,63 @@ void main() register uint32_t operator; register uint32_t downRecvLen; register uint32_t upRecvLen; + register uint32_t crc; - + uint8_t localData[512]; uint32_t slvNum; uint32_t totNum; register uint32_t isLast; register uint32_t flag; + *plic_enable_0_31 = 1 << 3 | 1 << 4 | 1 << 5 | 1 << 6; + *plic_priority_3 = 1; + *plic_priority_4 = 1; + *plic_priority_5 = 1; + *plic_priority_6 = 1; + *plic_threshold_0 = 0; - asm volatile ( - "li sp, 0\n" - ".4byte 0x600600b\n" - ); while(1){ + *cdr_softReset = 1; //复位脉冲 + *cdr_direct = 0; + isLast = *; - asm volatile( - "sw x0, 0x10(x0)\n" //cdr_softReset 写入任意值进行复位//复位脉冲 - "lw %0, 0x408(x0)\n" //ReadIsLast 获取是否为最后一个从机 - "sw x0, 0xc(x0)\n" //设置CDR方向 - : "+r"(isLast) - ); + // asm volatile( + // "sw x0, 0x10(x0)\n" //cdr_softReset 写入任意值进行复位//复位脉冲 + // "lw %0, 0x408(x0)\n" //ReadIsLast 获取是否为最后一个从机 + // "sw x0, 0xc(x0)\n" //设置CDR方向 + // : "+r"(isLast) + // ); // *WriteGpio = 0x01; //等待接收开始中断 - asm volatile ( - "1:\n" - "andi %0, sp, 0x04\n" - "beqz %0, 1b\n" - "andi sp, sp, 0xFB\n" - : "+r"(flag) - ); + while(!flag_intRxStart) + // asm volatile ( + // "1:\n" + // "andi %0, sp, 0x04\n" + // "beqz %0, 1b\n" + // "andi sp, sp, 0xFB\n" + // : "+r"(flag) + // ); + readDat = *cdr_rxFifo; + operator = (readDat >> 16) & 0xf; + downRecvLen = readDat >> 20; + readDat = *cdr_rxFifo; - asm volatile ( - "lw %0, 0x1c(x0)\n" //read rxfifo - "srli %1, %0, 16\n" // operator = readDat >> 16 - "srli %2, %1, 4\n" // downRecvLen = operator >> 4 - "andi %1, %1,0xf\n" // operator = operator & 0xf - "lw %0, 0x1c(x0)\n" //read rxfifo + // asm volatile ( + // "lw %0, 0x1c(x0)\n" //read rxfifo + // "srli %1, %0, 16\n" // operator = readDat >> 16 + // "srli %2, %1, 4\n" // downRecvLen = operator >> 4 + // "andi %1, %1,0xf\n" // operator = operator & 0xf + // "lw %0, 0x1c(x0)\n" //read rxfifo - : "+r"(readDat), "+r"(operator), "+r"(downRecvLen) - ); + // : "+r"(readDat), "+r"(operator), "+r"(downRecvLen) + // ); // *WriteGpio = 0x03; @@ -126,13 +134,17 @@ void main() //接收本地包 for( uint32_t i = 0; i < 2; i++ ) { - asm volatile ( - "andi %0, sp, 0x08\n" - "1:\n" - "bnez %0, 1b\n" //error - "lw %1, 0x1c(x0)\n" //read rxfifo - : "+r"(flag), "+r"(readDat) - ); + if( *flag_intRxError ){ + while(1); + } + *(localData+i) = *cdr_rxFifo; + // asm volatile ( + // "andi %0, sp, 0x08\n" + // "1:\n" + // "bnez %0, 1b\n" //error + // "lw %1, 0x1c(x0)\n" //read rxfifo + // : "+r"(flag), "+r"(readDat) + // ); } @@ -143,53 +155,74 @@ void main() if(!isLast){ // 下行转发新建包头 register uint32_t downSendHead; - asm volatile ( - "sw %0, 0x4(x0)\n" // *cdr_txLen = downRecvLen - "addi %2, %0, -8\n" //downSendLen = downRecvLen - 8; - "slli %1, %2, 20\n" // downSendHead = (downSendLen << 20) |( 0 << 16) | 0; - "sw %1, 0x8(x0)\n" //*cdr_txFifo = downSendHead - "sw x0, 0x8(x0)\n" //*cdr_txFifo = 0 - : "+r"(downRecvLen), "+r"(downSendHead), "+r"(downSendLen) - ); + + *cdr_txLen = downRecvLen; + downSendLen = downRecvLen - 8; + downSendHead = (downSendLen << 20) | ( 0 << 16) | 0; + *cdr_txFifo = downSendHead; + *cdr_txFifo = 0; + + // asm volatile ( + // "sw %0, 0x4(x0)\n" // *cdr_txLen = downRecvLen + // "addi %2, %0, -8\n" //downSendLen = downRecvLen - 8; + // "slli %1, %2, 20\n" // downSendHead = (downSendLen << 20) |( 0 << 16) | 0; + // "sw %1, 0x8(x0)\n" //*cdr_txFifo = downSendHead + // "sw x0, 0x8(x0)\n" //*cdr_txFifo = 0 + // : "+r"(downRecvLen), "+r"(downSendHead), "+r"(downSendLen) + // ); //下行转发负载 for( uint32_t i = 0; i < (downSendLen); i+=4 ){ //一次传4byte register uint32_t forData; - asm volatile ( - "andi %0, sp, 0x08\n" - "1:\n" - "bnez %0, 1b\n" //error 速度不够,不再检查接收 - "lw %1, 0x01c(x0)\n" - "sw %1, 0x008(x0)\n" - : - "+r"(flag), "+r"(forData) - ); + + if( flag_intRxError){ + while(1); + } + *cdr_txFifo = *cdr_rxFifo; + // asm volatile ( + // "andi %0, sp, 0x08\n" + // "1:\n" + // "bnez %0, 1b\n" //error 速度不够,不再检查接收 + // "lw %1, 0x01c(x0)\n" + // "sw %1, 0x008(x0)\n" + // : + // "+r"(flag), "+r"(forData) + // ); } } else{ //isLast //空转掉剩余负载 for( uint32_t i = 0; i < (downSendLen >> 2); i++ ){ //一次传4byte register uint32_t forData; - asm volatile ( - "andi %0, sp, 0x08\n" - "1:\n" - "bnez %0, 1b\n" //error 速度不够,不再检查接收 - "lw %1, 0x01c(x0)\n" - : "+r"(flag), "+r"(forData) - ); + + if( flag_intRxError ){ + while(1); + } + readDat = *cdr_rxFifo; + // asm volatile ( + // "andi %0, sp, 0x08\n" + // "1:\n" + // "bnez %0, 1b\n" //error 速度不够,不再检查接收 + // "lw %1, 0x01c(x0)\n" + // : "+r"(flag), "+r"(forData) + // ); } } // *WriteGpio = 0x0f; //CRC - asm volatile ( - "andi %0, sp, 0x08\n" - "1:\n" - "bnez %0, 1b\n" //error - "lw %1, 0x1c(x0)\n" //read rxfifo - : "+r"(flag), "+r"(readDat) - ); + if( flag_intRxError ){ + while(1); + } + crc = *cdr_rxFifo; + // asm volatile ( + // "andi %0, sp, 0x08\n" + // "1:\n" + // "bnez %0, 1b\n" //error + // "lw %1, 0x1c(x0)\n" //read rxfifo + // : "+r"(flag), "+r"(readDat) + // ); @@ -197,25 +230,29 @@ void main() // *WriteGpio = 0x1f; //等待接收完成标志 - asm volatile ( - "1:\n" - "andi %0, sp, 0x08\n" - "beqz %0, 1b\n" - "andi sp, sp, 0xF7\n" - : "+r"(flag) - ); + while(!flag_intRxEnd); + flag_intRxEnd = 0; + // asm volatile ( + // "1:\n" + // "andi %0, sp, 0x08\n" + // "beqz %0, 1b\n" + // "andi sp, sp, 0xF7\n" + // : "+r"(flag) + // ); // *WriteGpio = 0x3f; if(!isLast){ //等待发送完成标志 - asm volatile ( - "1:\n" - "andi %0, sp, 0x01\n" - "beqz %0, 1b\n" - "andi sp, sp, 0xFE\n" - :"+r"(flag) - ); + while(!flag_intTxEnd); + flag_intTxEnd = 0; + // asm volatile ( + // "1:\n" + // "andi %0, sp, 0x01\n" + // "beqz %0, 1b\n" + // "andi sp, sp, 0xFE\n" + // :"+r"(flag) + // ); } // *WriteGpio = 0x7f; @@ -224,96 +261,127 @@ void main() register uint32_t txLen; register uint32_t txHeader; - asm volatile( - "sw x0, 0x10(x0)\n" //cdr_softReset 写入任意值进行复位//复位脉冲 - "sw %0, 0xc(x0)\n" //设置CDR方向 - : "+r"(one) - ); + *cdr_softReset = 1; + *cdr_direct = 1; + // asm volatile( + // "sw x0, 0x10(x0)\n" //cdr_softReset 写入任意值进行复位//复位脉冲 + // "sw %0, 0xc(x0)\n" //设置CDR方向 + // : "+r"(one) + // ); if(!isLast){ //上行转发 //接收第一个包 - asm volatile ( - "1:\n" - "andi %0, sp, 0x04\n" - "beqz %0, 1b\n" - "andi sp, sp, 0xFB\n" - :"+r"(flag) - ); + + while(!flag_intRxStart); + flag_intRxStart = 0; + // asm volatile ( + // "1:\n" + // "andi %0, sp, 0x04\n" + // "beqz %0, 1b\n" + // "andi sp, sp, 0xFB\n" + // :"+r"(flag) + // ); - //发送上行包头 - asm volatile ( - "lw %0, 0x1c(x0)\n" //read rxfifo - "srli %1, %0, 20\n" // upRecvLen = readDat >> 20 - "addi %2, %1, 16\n" //txLen = upRecvLen + 16 - "addi %3, %1, 8\n" //txHeader = upRecvLen + 8 - "slli %3, %3, 20\n" //txHeader = txHeader << 20 |( 0 << 16) | 0 - "sw %2, 0x4(x0)\n" //*cdr_txLen = txLen - "sw %3, 0x8(x0)\n" //*cdr_txFifo = txHeader - "sw x0, 0x8(x0)\n" //*cdr_txFifo = 0 + //接收第一个包 + if(flag_intRxError){while(1);} + readDat = *cdr_rxFifo; + upRecvLen = readDat >> 20; + txLen = upRecvLen + 16; + txHeader = upRecvLen + 8; + txHeader = (txHeader << 20) | ( 0 << 16) | 0; - : "+r"(readDat), "+r"(upRecvLen), "+r"( txLen ), "+r"( txHeader ) - ); + //发送上行包头 + *cdr_txLen = txLen; + *cdr_txFifo = txHeader; + *cdr_txFifo = 0; + + // asm volatile ( + // "lw %0, 0x1c(x0)\n" //read rxfifo + // "srli %1, %0, 20\n" // upRecvLen = readDat >> 20 + // "addi %2, %1, 16\n" //txLen = upRecvLen + 16 + // "addi %3, %1, 8\n" //txHeader = upRecvLen + 8 + // "slli %3, %3, 20\n" //txHeader = txHeader << 20 |( 0 << 16) | 0 + // "sw %2, 0x4(x0)\n" //*cdr_txLen = txLen + // "sw %3, 0x8(x0)\n" //*cdr_txFifo = txHeader + // "sw x0, 0x8(x0)\n" //*cdr_txFifo = 0 + + // : "+r"(readDat), "+r"(upRecvLen), "+r"( txLen ), "+r"( txHeader ) + // ); for( uint32_t i = 0; i < 8/4; i ++ ){ - asm volatile ( - "sw x0, 0x8(x0)\n" //*cdr_txFifo = 0; - ); + *cdr_txFifo = 0; + // asm volatile ( + // "sw x0, 0x8(x0)\n" //*cdr_txFifo = 0; + // ); } //接收第二个包 - asm volatile ( - "andi %0, sp, 0x08\n" - "1:\n" - "bnez %0, 1b\n" //error //速度不够,不校验 - "lw %1, 0x1c(x0)\n" //read rxfifo - :"+r"(flag), "+r"(readDat) - - ); + if(flag_intRxError){while(1);} + readDat = *cdr_rxFifo; + // asm volatile ( + // "andi %0, sp, 0x08\n" + // "1:\n" + // "bnez %0, 1b\n" //error //速度不够,不校验 + // "lw %1, 0x1c(x0)\n" //read rxfifo + // :"+r"(flag), "+r"(readDat) + // ); //上行转发负载 for( uint32_t i = 0; i < (upRecvLen); i += 4 ){ //一次传4byte register uint32_t forData; - asm volatile ( - "andi %0, sp, 0x80\n" - "1:\n" - "bnez %0, 1b\n" //error 速度不够,不再检查接收 - "lw %1, 0x01c(x0)\n" - "sw %1, 0x008(x0)\n" - :"+r"(flag), "+r"(forData) - ); + + if( flag_intRxError ){ + while(1); + } + *cdr_txFifo = *cdr_rxFifo; + + // asm volatile ( + // "andi %0, sp, 0x80\n" + // "1:\n" + // "bnez %0, 1b\n" //error 速度不够,不再检查接收 + // "lw %1, 0x01c(x0)\n" + // "sw %1, 0x008(x0)\n" + // :"+r"(flag), "+r"(forData) + // ); } //CRC - asm volatile ( - "andi %0, sp, 0x08\n" - "1:\n" - "bnez %0, 1b\n" //error - "lw %0, 0x1c(x0)\n" //read rxfifo - :"+r"(flag), "+r"(readDat) - ); + if( flag_intRxError ){ + while(1); + } + crc = *cdr_rxFifo; + // asm volatile ( + // "andi %0, sp, 0x08\n" + // "1:\n" + // "bnez %0, 1b\n" //error + // "lw %0, 0x1c(x0)\n" //read rxfifo + // :"+r"(flag), "+r"(readDat) + // ); //等待接收完成标志 - asm volatile ( - "1:\n" - "andi %0, sp, 0x08\n" - "beqz %0, 1b\n" - "andi sp, sp, 0xF7\n" - :"+r"(flag) - ); + while(!flag_intRxEnd); + flag_intRxEnd = 0; + // asm volatile ( + // "1:\n" + // "andi %0, sp, 0x08\n" + // "beqz %0, 1b\n" + // "andi sp, sp, 0xF7\n" + // :"+r"(flag) + // ); totNum = slvNum + (upRecvLen >> 3) - 1; } else { //islast @@ -321,36 +389,40 @@ void main() //发送上行包头 + txLen = upRecvLen + 16; + txHeader = ( 8 << 20 ) | ( 0 << 16) | 0; + *cdr_txLen = txLen; + *cdr_txFifo = txHeader; + *cdr_txFifo = 0; + // asm volatile ( + // "li %0, 16\n" //txLen = upRecvLen + 16 + // "sw %0, 0x4(x0)\n" //*cdr_txLen = txLen + // "lui %1, 0x800\n" //txHeader = 8 << 20 |( 0 << 16) | 0 + // "sw %1, 0x8(x0)\n" //*cdr_txFifo = txHeader + // "sw x0, 0x8(x0)\n" //*cdr_txFifo = 0 - asm volatile ( - - "li %0, 16\n" //txLen = upRecvLen + 16 - "sw %0, 0x4(x0)\n" //*cdr_txLen = txLen - "lui %1, 0x800\n" //txHeader = 8 << 20 |( 0 << 16) | 0 - "sw %1, 0x8(x0)\n" //*cdr_txFifo = txHeader - "sw x0, 0x8(x0)\n" //*cdr_txFifo = 0 - - : "+r"( txLen ), "+r"( txHeader ) - ); + // : "+r"( txLen ), "+r"( txHeader ) + // ); for( uint32_t i = 0; i < 8/4; i ++ ){ - asm volatile ( - "sw x0, 0x8(x0)\n" //*cdr_txFifo = 0; - ); + *cdr_txFifo = 0; + // asm volatile ( + // "sw x0, 0x8(x0)\n" //*cdr_txFifo = 0; + // ); } - - } //等待发送完成标志 - asm volatile ( - "1:\n" - "andi %0, sp, 0x01\n" - "beqz %0, 1b\n" - "andi sp, sp, 0xFE\n" - :"+r"(flag) - ); + while(!flag_intTxEnd); + flag_intTxEnd = 0; + // asm volatile ( + // "1:\n" + // "andi %0, sp, 0x01\n" + // "beqz %0, 1b\n" + // "andi sp, sp, 0xFE\n" + // :"+r"(flag) + // ); slvNum = 64 - ( downRecvLen >> 3 ); *WriteGpio = 1 << slvNum; diff --git a/tb/sw/src/custom_ops.S.bk b/tb/sw/src/custom_ops.S.bk deleted file mode 100644 index 71889b9..0000000 --- a/tb/sw/src/custom_ops.S.bk +++ /dev/null @@ -1,102 +0,0 @@ -// This is free and unencumbered software released into the public domain. -// -// Anyone is free to copy, modify, publish, use, compile, sell, or -// distribute this software, either in source code form or as a compiled -// binary, for any purpose, commercial or non-commercial, and by any -// means. - -#define regnum_q0 0 -#define regnum_q1 1 -#define regnum_q2 2 -#define regnum_q3 3 - -#define regnum_x0 0 -#define regnum_x1 1 -#define regnum_x2 2 -#define regnum_x3 3 -#define regnum_x4 4 -#define regnum_x5 5 -#define regnum_x6 6 -#define regnum_x7 7 -#define regnum_x8 8 -#define regnum_x9 9 -#define regnum_x10 10 -#define regnum_x11 11 -#define regnum_x12 12 -#define regnum_x13 13 -#define regnum_x14 14 -#define regnum_x15 15 -#define regnum_x16 16 -#define regnum_x17 17 -#define regnum_x18 18 -#define regnum_x19 19 -#define regnum_x20 20 -#define regnum_x21 21 -#define regnum_x22 22 -#define regnum_x23 23 -#define regnum_x24 24 -#define regnum_x25 25 -#define regnum_x26 26 -#define regnum_x27 27 -#define regnum_x28 28 -#define regnum_x29 29 -#define regnum_x30 30 -#define regnum_x31 31 - -#define regnum_zero 0 -#define regnum_ra 1 -#define regnum_sp 2 -#define regnum_gp 3 -#define regnum_tp 4 -#define regnum_t0 5 -#define regnum_t1 6 -#define regnum_t2 7 -#define regnum_s0 8 -#define regnum_s1 9 -#define regnum_a0 10 -#define regnum_a1 11 -#define regnum_a2 12 -#define regnum_a3 13 -#define regnum_a4 14 -#define regnum_a5 15 -#define regnum_a6 16 -#define regnum_a7 17 -#define regnum_s2 18 -#define regnum_s3 19 -#define regnum_s4 20 -#define regnum_s5 21 -#define regnum_s6 22 -#define regnum_s7 23 -#define regnum_s8 24 -#define regnum_s9 25 -#define regnum_s10 26 -#define regnum_s11 27 -#define regnum_t3 28 -#define regnum_t4 29 -#define regnum_t5 30 -#define regnum_t6 31 - -// x8 is s0 and also fp -#define regnum_fp 8 - -#define r_type_insn(_f7, _rs2, _rs1, _f3, _rd, _opc) \ -.word (((_f7) << 25) | ((_rs2) << 20) | ((_rs1) << 15) | ((_f3) << 12) | ((_rd) << 7) | ((_opc) << 0)) - -#define picorv32_getq_insn(_rd, _qs) \ -r_type_insn(0b0000000, 0, regnum_ ## _qs, 0b100, regnum_ ## _rd, 0b0001011) - -#define picorv32_setq_insn(_qd, _rs) \ -r_type_insn(0b0000001, 0, regnum_ ## _rs, 0b010, regnum_ ## _qd, 0b0001011) - -#define picorv32_retirq_insn() \ -r_type_insn(0b0000010, 0, 0, 0b000, 0, 0b0001011) - -#define picorv32_maskirq_insn(_rd, _rs) \ -r_type_insn(0b0000011, 0, regnum_ ## _rs, 0b110, regnum_ ## _rd, 0b0001011) - -#define picorv32_waitirq_insn(_rd) \ -r_type_insn(0b0000100, 0, 0, 0b100, regnum_ ## _rd, 0b0001011) - -#define picorv32_timer_insn(_rd, _rs) \ -r_type_insn(0b0000101, 0, regnum_ ## _rs, 0b110, regnum_ ## _rd, 0b0001011) - diff --git a/tb/sw/src/mstMain.S.bk b/tb/sw/src/mstMain.S.bk deleted file mode 100644 index 23a73fa..0000000 --- a/tb/sw/src/mstMain.S.bk +++ /dev/null @@ -1,56 +0,0 @@ - -#define cdr_status 0x000 -#define cdr_txLen 0x004 -#define cdr_txFifo 0x008 -#define cdr_direct 0x00c - -#define cdr_softReset 0x010 -#define cdr_rxLen 0x018 -#define cdr_rxFifo 0x01c - - - -.global main - - -main: - sw x0, 0x010(x0) # 软复位,写入任意值,0也可以 - sw x0, 0x00c(x0) # 配置方向,下行 - - li x6, 520 - sw x6, 0x004(x0) #cdr_0_tx_txLen - - lui x6, 0x20000 - sw x6, 0x008(x0) # 发送len op param0 - sw x0, 0x008(x0) # 发送 param1 param2 - li x6, 128 # 设置循环次数 - li x10, 0x1234 -1: - # 向cdr_0_tx_txFifo地址写入0x55,循环32次 - - sw x10, 0x008(x0) # 向cdr_0_tx_txFifo写入0 - addi x6, x6, -1 # 递减计数器 - bnez x6, 1b # 如果计数器不为0,则继续循环 - - -2: - andi ra, sp, 0x01 # 等待发送完成标志位 - beqz ra, 2b - andi sp, sp, 0xFE - - sw x0, 0x010(x0) # 软复位,写入任意值,0也可以 - li x6, 1 - sw x6, 0x00c(x0) # 配置方向,上行 - - - - -3: - j 2b - - - - - - - diff --git a/tb/sw/src/slvMain.S.bk b/tb/sw/src/slvMain.S.bk deleted file mode 100644 index 68d6324..0000000 --- a/tb/sw/src/slvMain.S.bk +++ /dev/null @@ -1,175 +0,0 @@ - -#define cdr_0_tx_status 0x40000000 -#define cdr_0_tx_txLen 0x40000004 -#define cdr_0_tx_txFifo 0x40000008 -#define cdr_0_rx_softReset 0x40000010 -#define cdr_0_rx_status 0x40000014 -#define cdr_0_rx_rxLen 0x40000018 -#define cdr_0_rx_rxFifo 0x4000001c - -#define cdr_1_tx_status 0x40000080 -#define cdr_1_tx_txLen 0x40000084 -#define cdr_1_tx_txFifo 0x40000088 -#define cdr_1_rx_softReset 0x40000090 -#define cdr_1_rx_status 0x40000094 -#define cdr_1_rx_rxLen 0x40000098 -#define cdr_1_rx_rxFifo 0x4000009c -#define isWriteGpio 0x60000000 -#define isReadGpio 0x60000000 -#define isReadIsLast 0x60000008 - - -# x2 计数器 -# x5 目标计数值 -# x6 1)操作数 从站号 -# x7 1) 长度 -# x8 1)临时变量 -# x9 从站号 -# x10 操作数和len 参数0 -# x11 两个参数 -# x12 临时转发 -# x13 1)装填基地址 -# x14 -# x15 中断镜像 - -.global main - -@ io.interrupt(0) := intTxError -@ io.interrupt(1) := intTxFifoFull -@ io.interrupt(2) := intTxFinish - -@ io.interrupt(3) := intRxError -@ io.interrupt(4) := intRxValid - -main: - beqz x15, main # 有中断进来,否则在此地等待 - bneq x15, 0x10, error # 第一个中断应该是下行接收中断0x10,接收数据到来0 下行 - li x15, 0 # 清x15的对应比特 - - - lui x13, %hi(0x40000000) # 装填基地址 - lw x10, 0x1c(x13) # 读rxfifo, 获得长度,操作,参数0 - -1: # 包头2 - beqz x15, 1b # 有中断进来,否则在此地等待 - bneq x15, 0x10, error # 中断应该是下行接收中断0x10,接收数据到来0 下行 - li x15, 0 # 清x15的对应比特 - - lw x11, 0x1c(x13) # 读rxfifo, 获得参数1,参数2 - -#本地数据 - # 确认本地数据长度 - srli x6, x10, 16 # 获得操作数和长度, 右移16位 - srli x7, x6, 4 # 获得长度, 右移4位 - andi x6, x6, 0xf # 获得操作数取低4比特 - - beqz x6, opInit # 若操作数为0,跳转初始化 - li x8, 1 - beq x6, x8, opSync # 若操作数为1,跳转同步 - li x8, 2 - beq x6, x8, opBCast # 若操作数为1,跳转广播 - li x8, 3 - beq x6, x8, opUCast # 若操作数为1,跳转广播 - j error # 未定义操作数,报错 - -opInit: - srli x6, x7, 3 # 接收长度除以8 - sub x6, x0, x6 # x6=-x6 - addi x6, x6, 64 # x6=x6+64 - - li x2 # 接收计数器清零启动 - -opSync: - j error # 未定义操作数,报错 -opBCast: - j error # 未定义操作数,报错 -opUCast: - j error # 未定义操作数,报错 - - -2: # 下行本地数据 - beqz x15, 2b # 有中断进来,否则在此地等待 - bneq x15, 0x10, error # 中断应该是下行接收中断0x10,接收数据到来0 下行 - li x15, 0 # 清x15的对应比特 - # 读rxfifo, 获得本地数据 - # 接收计数器+1 - # 比较计数器是否收完本地数据,没有则回到2 - - - -downpay: - - beqz x15, 1b # 有中断进来,否则在此地等待 - bneq x15, 0x10, error # 中断应该是下行接收中断0x10,接收数据到来0 下行,下行发送不应该full或者其它,否则错误 - - - - - # 确认下行转发操作 - # 向下行发送写入长度,操作码,参数0 - # 向下行发送写入参数1, 参数2 - - -1: -bnez x15, 0x10, 2f -2: - - - -error: - - -3: -4: -5: -6: -7: -8: - - - - - beq x15, 0x200, 2f # 接收数据到来1 上行 - - beq x15, 0x01, 1f # 发送错误0 - beq x15, 0x02, 2f # 发送fifo满0 - beq x15, 0x04, 3f # 发送完成0 - beq x15, 0x08, 4f # 接收错误0 - beq x15, 0x20, 6f # 发送错误1 - beq x15, 0x40, 7f # 发送fifo满1 - beq x15, 0x80, 8f # 发送完成1 - beq x15, 0x100, 9f # 接收错误1 - j main # 循环等待直到中断到来 - - - - - lui x5, %hi(cdr_0_tx_status) - - li x6, 128 - sw x6, 4(x5) #cdr_0_tx_txLen - - li x6, 32 # 设置循环次数 -1: - beqz x15, 3f # 如果x10为0,则跳到3 -2: - li x15, 0 # 清标志位 - lw x7, 0(x5) # 读取cdr_0_tx_status的值 - andi x7, x7, 0x2 # 检查第1比特(位1) - bnez x7, 2b # 如果第1比特不为0,则回到2处继续循环 - -3: - # 向cdr_0_tx_txFifo地址写入0x55,循环32次 - sw x6, 8(x5) # 向cdr_0_tx_txFifo写入0x55 - addi x6, x6, -1 # 递减计数器 - bnez x6, 1b # 如果计数器不为0,则继续循环 - -4: - j 4b - - - - - - - diff --git a/tb/sw/src/slvStartup.S b/tb/sw/src/slvStartup.S index 439c1bb..09a9062 100644 --- a/tb/sw/src/slvStartup.S +++ b/tb/sw/src/slvStartup.S @@ -1,11 +1,9 @@ - .extern main -.extern trap_entry - -.globl _prog_start +.extern plic_handle +.globl prog_start .section .text.init @@ -13,6 +11,12 @@ _prog_start: la t0, trap_entry csrw mtvec, t0 + li t0, 1 << 11 + csrw mie, t0 + + csrr t0, mstatus + ori t0, t0, 1<<3 + csrw mstatus, t0 li x1, 0 li x2, 0 @@ -52,15 +56,97 @@ _prog_start: ecall -# .balign 32 -# .section .trap_entry, "ax", %progbits -# trap_entry: - # io.interrupt(0) := intTxError - # io.interrupt(1) := intRxError - # io.interrupt(2) := intRxStart - # io.interrupt(3) := intRxEnd +.balign 32 +.section .trap_entry, "ax", %progbits +trap_entry: + + addi sp,sp,-136 + sw ra,4(sp) + sw sp,8(sp) + sw gp,12(sp) + sw tp,16(sp) + sw t0,20(sp) + sw t1,24(sp) + sw t2,28(sp) + sw s0,32(sp) + sw s1,36(sp) + sw a0,40(sp) + sw a1,44(sp) + sw a2,48(sp) + sw a3,52(sp) + sw a4,56(sp) + sw a5,60(sp) + sw a6,64(sp) + sw a7,68(sp) + sw s2,72(sp) + sw s3,76(sp) + sw s4,80(sp) + sw s5,84(sp) + sw s6,88(sp) + sw s7,92(sp) + sw s8,96(sp) + sw s9,100(sp) + sw s10,104(sp) + sw s11,108(sp) + sw t3,112(sp) + sw t4,116(sp) + sw t5,120(sp) + sw t6,124(sp) + csrr t0, mstatus # 读取 mstatus 寄存器 + andi t0, t0, ~(1 << 3) # 清除 MIE 位 (全局中断禁用) + csrw mstatus, t0 # 写回 mstatus 寄存器 + + + + call plic_handle + + csrr t0, mstatus + ori t0, t0, 1<<3 + csrw mstatus, t0 + + + + + + lw ra,4(sp) + lw sp,8(sp) + lw gp,12(sp) + lw tp,16(sp) + lw t0,20(sp) + lw t1,24(sp) + lw t2,28(sp) + lw s0,32(sp) + lw s1,36(sp) + lw a0,40(sp) + lw a1,44(sp) + lw a2,48(sp) + lw a3,52(sp) + lw a4,56(sp) + lw a5,60(sp) + lw a6,64(sp) + lw a7,68(sp) + lw s2,72(sp) + lw s3,76(sp) + lw s4,80(sp) + lw s5,84(sp) + lw s6,88(sp) + lw s7,92(sp) + lw s8,96(sp) + lw s9,100(sp) + lw s10,104(sp) + lw s11,108(sp) + lw t3,112(sp) + lw t4,116(sp) + lw t5,120(sp) + lw t6,124(sp) + addi sp,sp,136 + + + + mret + diff --git a/tb/sw/tl2cdr/tl2cdr.c b/tb/sw/tl2cdr/tl2cdr.c index b2b5534..ac7db2d 100644 --- a/tb/sw/tl2cdr/tl2cdr.c +++ b/tb/sw/tl2cdr/tl2cdr.c @@ -77,11 +77,11 @@ void cdr_simple_rx(uint32_t* rxLen, uint8_t* operator, uint8_t* data){ uint32_t readDat; readDat = *cdr_rxFifo; - &operator = (readDat >> 16) & 0xf; - &rxLen = readDat >> 20; + *operator = (readDat >> 16) & 0xf; + *rxLen = readDat >> 20; readDat = *cdr_rxFifo; - for( uint32_t i = 0; i < (&rxLen >> 2); i ++ ){ //一次传4byte + for( uint32_t i = 0; i < ( *rxLen >> 2); i ++ ){ //一次传4byte readDat = *cdr_rxFifo; data[4*i+1] = (uint8_t)( (readDat >> 0) & 0xFF); data[4*i+0] = (uint8_t)( (readDat >> 8) & 0xFF); diff --git a/tb/verilator/SimTop.v b/tb/verilator/SimTop.v index ae8f564..03b2c97 100644 --- a/tb/verilator/SimTop.v +++ b/tb/verilator/SimTop.v @@ -84,7 +84,7 @@ ExampleRocketSystem s_rocket_mst( .cdrio_dDatOut(dDatSer[0]) ); -/* + ExampleRocketSystem s_rocket_slv0( .clock(clock), .reset(reset), @@ -254,7 +254,7 @@ ExampleRocketSystem s_rocket_slv2( .cdrio_dDatIn(dDatSer[2]), .cdrio_dDatOut() ); -*/ + @@ -317,6 +317,12 @@ ExampleRocketSystem s_rocket_slv2( +initial begin + s_rocket_mst.tile_prci_domain.tile_reset_domain_tile.core.CoreID = 0; + s_rocket_slv0.tile_prci_domain.tile_reset_domain_tile.core.CoreID = 1; + s_rocket_slv1.tile_prci_domain.tile_reset_domain_tile.core.CoreID = 2; + s_rocket_slv2.tile_prci_domain.tile_reset_domain_tile.core.CoreID = 3; +end string testName; @@ -339,7 +345,7 @@ initial begin #20 $readmemh("./tb/sw/build/mstTest.verilog", mem0); - for ( i = 0; i < DP; i = i + 1 ) begin + for ( i = 0; i < DP; i = i + 1 ) begin if ( mem0[i*4+0] || mem0[i*4+1] || mem0[i*4+2] || mem0[i*4+3] ) begin `MEM0[i] = {mem0[i*4+3], mem0[i*4+2], mem0[i*4+1], mem0[i*4+0]}; end @@ -350,35 +356,35 @@ initial begin // $display("MEM0[%d] = %h", i, `MEM0[i]); end - // $readmemh("./tb/sw/build/slvTest.verilog", mem1); - // for ( i = 0; i < DP; i = i + 1 ) begin - // if ( mem1[i*4+0] || mem1[i*4+1] || mem1[i*4+2] || mem1[i*4+3] ) begin - // `MEM1[i] = {mem1[i*4+3], mem1[i*4+2], mem1[i*4+1], mem1[i*4+0]}; - // end - // else begin - // `MEM1[i] = 32'h0; - // end - // end + $readmemh("./tb/sw/build/slvTest.verilog", mem1); + for ( i = 0; i < DP; i = i + 1 ) begin + if ( mem1[i*4+0] || mem1[i*4+1] || mem1[i*4+2] || mem1[i*4+3] ) begin + `MEM1[i] = {mem1[i*4+3], mem1[i*4+2], mem1[i*4+1], mem1[i*4+0]}; + end + else begin + `MEM1[i] = 32'h0; + end + end - // $readmemh("./tb/sw/build/slvTest.verilog", mem2); - // for ( i = 0; i < DP; i = i + 1 ) begin - // if ( mem2[i*4+0] || mem2[i*4+1] || mem2[i*4+2] || mem2[i*4+3] ) begin - // `MEM2[i] = {mem2[i*4+3], mem2[i*4+2], mem2[i*4+1], mem2[i*4+0]}; - // end - // else begin - // `MEM2[i] = 32'h0; - // end - // end + $readmemh("./tb/sw/build/slvTest.verilog", mem2); + for ( i = 0; i < DP; i = i + 1 ) begin + if ( mem2[i*4+0] || mem2[i*4+1] || mem2[i*4+2] || mem2[i*4+3] ) begin + `MEM2[i] = {mem2[i*4+3], mem2[i*4+2], mem2[i*4+1], mem2[i*4+0]}; + end + else begin + `MEM2[i] = 32'h0; + end + end - // $readmemh("./tb/sw/build/slvTest.verilog", mem3); - // for ( i = 0; i < DP; i = i + 1 ) begin - // if ( mem3[i*4+0] || mem3[i*4+1] || mem3[i*4+2] || mem3[i*4+3] ) begin - // `MEM3[i] = {mem3[i*4+3], mem3[i*4+2], mem3[i*4+1], mem3[i*4+0]}; - // end - // else begin - // `MEM3[i] = 32'h0; - // end - // end + $readmemh("./tb/sw/build/slvTest.verilog", mem3); + for ( i = 0; i < DP; i = i + 1 ) begin + if ( mem3[i*4+0] || mem3[i*4+1] || mem3[i*4+2] || mem3[i*4+3] ) begin + `MEM3[i] = {mem3[i*4+3], mem3[i*4+2], mem3[i*4+1], mem3[i*4+0]}; + end + else begin + `MEM3[i] = 32'h0; + end + end end diff --git a/tb/verilator/plusarg_reader.v b/tb/verilator/plusarg_reader.v new file mode 100644 index 0000000..6d4ad44 --- /dev/null +++ b/tb/verilator/plusarg_reader.v @@ -0,0 +1,17 @@ +// See LICENSE.SiFive for license details. + +//VCS coverage exclude_file + +// No default parameter values are intended, nor does IEEE 1800-2012 require them (clause A.2.4 param_assignment), +// but Incisive demands them. These default values should never be used. +module plusarg_reader #( + parameter FORMAT="borked=%d", + parameter WIDTH=1, + parameter [WIDTH-1:0] DEFAULT=0 +) ( + output [WIDTH-1:0] out +); + +assign out = DEFAULT; + +endmodule