写完软件需要加gpio

This commit is contained in:
Ruige Lee (WSL)
2025-01-16 16:34:48 +08:00
parent f63e3a831b
commit e54ddab4e2
9 changed files with 419 additions and 572 deletions

View File

@@ -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:

View File

@@ -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)
// );
//接收第一个包
if(flag_intRxError){while(1);}
readDat = *cdr_rxFifo;
upRecvLen = readDat >> 20;
txLen = upRecvLen + 16;
txHeader = upRecvLen + 8;
txHeader = (txHeader << 20) | ( 0 << 16) | 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
*cdr_txLen = txLen;
*cdr_txFifo = txHeader;
*cdr_txFifo = 0;
: "+r"(readDat), "+r"(upRecvLen), "+r"( txLen ), "+r"( txHeader )
);
// 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;

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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