mirror of
https://github.com/handsomezhuzhu/2025-yatcpu.git
synced 2026-02-20 20:10:14 +00:00
lab2全部完成
This commit is contained in:
@@ -1,7 +1,13 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(sbt \"testOnly *BusTest\")"
|
||||
"Bash(sbt \"testOnly riscv.MemoryTestF\")",
|
||||
"Bash(mill yatcpu.test.testOnly:*)",
|
||||
"Bash(powershell.exe -Command \"sbt ''testOnly riscv.MemoryTestF''\")",
|
||||
"Bash(powershell.exe -Command \"& ''C:\\Program Files (x86)\\sbt\\bin\\sbt.bat'' ''testOnly riscv.MemoryTestF''\")",
|
||||
"Bash(powershell.exe -Command \"java -version\")",
|
||||
"Bash(powershell.exe -Command \"$env:JAVA_HOME=''C:\\Users\\26586\\.jdks\\temurin-17.0.16''; $env:PATH=''C:\\Users\\26586\\.jdks\\temurin-17.0.16\\bin;''+$env:PATH; cd ''E:\\jizu\\2025-fall-yatcpu-repo\\lab4''; & ''C:\\Program Files (x86)\\sbt\\bin\\sbt.bat'' ''testOnly riscv.MemoryTestF''\")",
|
||||
"Bash(cmd.exe /c \"set JAVA_HOME=C:\\Users\\26586\\.jdks\\temurin-17.0.16 && set PATH=C:\\Users\\26586\\.jdks\\temurin-17.0.16\\bin;%PATH% && \"\"C:\\Program Files (x86)\\sbt\\bin\\sbt.bat\"\" \"\"testOnly riscv.MemoryTestF\"\"\")"
|
||||
],
|
||||
"deny": [],
|
||||
"ask": []
|
||||
|
||||
@@ -114,7 +114,7 @@ class AXI4LiteMasterBundle(addrWidth: Int, dataWidth: Int) extends Bundle {
|
||||
}
|
||||
|
||||
object AXI4LiteStates extends ChiselEnum {
|
||||
val Idle, ReadAddr, ReadData, WriteAddr, WriteData, WriteResp = Value
|
||||
val Idle, ReadAddr, ReadDataWait, ReadData, WriteAddr, WriteData, WriteResp = Value
|
||||
}
|
||||
|
||||
class AXI4LiteSlave(addrWidth: Int, dataWidth: Int) extends Module {
|
||||
@@ -142,8 +142,6 @@ class AXI4LiteSlave(addrWidth: Int, dataWidth: Int) extends Module {
|
||||
val RRESP = RegInit(0.U(AXI4Lite.respWidth))
|
||||
io.channels.read_data_channel.RRESP := RRESP
|
||||
|
||||
io.channels.read_data_channel.RDATA := io.bundle.read_data
|
||||
|
||||
val AWREADY = RegInit(false.B)
|
||||
io.channels.write_address_channel.AWREADY := AWREADY
|
||||
val WREADY = RegInit(false.B)
|
||||
@@ -154,89 +152,87 @@ class AXI4LiteSlave(addrWidth: Int, dataWidth: Int) extends Module {
|
||||
val BRESP = WireInit(0.U(AXI4Lite.respWidth))
|
||||
io.channels.write_response_channel.BRESP := BRESP
|
||||
//lab4(BUS)
|
||||
// 读数据寄存器,保证 RDATA 在 RVALID 为高时稳定
|
||||
val rdataReg = RegInit(0.U(dataWidth.W))
|
||||
io.channels.read_data_channel.RDATA := rdataReg
|
||||
|
||||
switch(state) {
|
||||
is(AXI4LiteStates.Idle) {
|
||||
// 默认状态:所有控制信号为低
|
||||
// 默认:清除控制信号
|
||||
ARREADY := false.B
|
||||
RVALID := false.B
|
||||
AWREADY := false.B
|
||||
WREADY := false.B
|
||||
BVALID := false.B
|
||||
read := false.B
|
||||
write := false.B
|
||||
read_issued := false.B
|
||||
|
||||
// 检测读地址通道的请求
|
||||
// 优先响应读请求
|
||||
when(io.channels.read_address_channel.ARVALID) {
|
||||
read := false.B // 清除之前的read
|
||||
state := AXI4LiteStates.ReadAddr
|
||||
addr := io.channels.read_address_channel.ARADDR
|
||||
ARREADY := true.B
|
||||
state := AXI4LiteStates.ReadAddr
|
||||
}.elsewhen(io.channels.write_address_channel.AWVALID) {
|
||||
write := false.B // 清除之前的write
|
||||
// 检测写地址通道的请求
|
||||
state := AXI4LiteStates.WriteAddr
|
||||
addr := io.channels.write_address_channel.AWADDR
|
||||
AWREADY := true.B
|
||||
}.otherwise {
|
||||
// 没有新请求时,延迟清除read/write信号
|
||||
read := false.B
|
||||
write := false.B
|
||||
state := AXI4LiteStates.WriteAddr
|
||||
}
|
||||
}
|
||||
|
||||
is(AXI4LiteStates.ReadAddr) {
|
||||
// 读地址握手完成,发起读请求并进入ReadData
|
||||
// 已经完成 ARVALID/ARREADY 握手,将地址送给从设备并发起一次读
|
||||
ARREADY := false.B
|
||||
read := true.B
|
||||
read_issued := false.B
|
||||
state := AXI4LiteStates.ReadData
|
||||
}
|
||||
|
||||
is(AXI4LiteStates.ReadData) {
|
||||
// 保持read信号有效
|
||||
// 保持对设备的读请求,等待设备返回 read_valid
|
||||
read := true.B
|
||||
|
||||
when(!read_issued) {
|
||||
// 第一个周期:等待Memory准备数据
|
||||
// 第一个周期:等待 SyncReadMem 数据准备(需要一个周期延迟)
|
||||
read_issued := true.B
|
||||
}.otherwise {
|
||||
// 第二个周期及之后:检查数据是否准备好
|
||||
when(!RVALID && io.bundle.read_valid) {
|
||||
// 数据准备好,置RVALID
|
||||
RVALID := true.B
|
||||
}.elsewhen(RVALID && io.channels.read_data_channel.RREADY) {
|
||||
// 握手完成,返回Idle(read会在Idle状态延迟清除)
|
||||
RVALID := false.B
|
||||
read_issued := false.B
|
||||
state := AXI4LiteStates.Idle
|
||||
}
|
||||
}.elsewhen(io.bundle.read_valid && !RVALID) {
|
||||
// 设备已经准备好数据,将其锁存并拉高 RVALID
|
||||
rdataReg := io.bundle.read_data
|
||||
RVALID := true.B
|
||||
}.elsewhen(RVALID && io.channels.read_data_channel.RREADY) {
|
||||
// 主机已经接收数据,完成一次读事务
|
||||
RVALID := false.B
|
||||
read := false.B
|
||||
read_issued := false.B
|
||||
state := AXI4LiteStates.Idle
|
||||
}
|
||||
}
|
||||
|
||||
is(AXI4LiteStates.WriteAddr) {
|
||||
// 写地址握手完成,等待写数据
|
||||
// 写地址握手结束,等待写数据
|
||||
AWREADY := false.B
|
||||
when(io.channels.write_data_channel.WVALID) {
|
||||
// 收到写数据
|
||||
state := AXI4LiteStates.WriteData
|
||||
// 收到写数据,锁存写数据及写选通
|
||||
write_data := io.channels.write_data_channel.WDATA
|
||||
for (i <- 0 until Parameters.WordSize) {
|
||||
write_strobe(i) := io.channels.write_data_channel.WSTRB(i)
|
||||
}
|
||||
WREADY := true.B
|
||||
write := true.B
|
||||
state := AXI4LiteStates.WriteData
|
||||
}
|
||||
}
|
||||
|
||||
is(AXI4LiteStates.WriteData) {
|
||||
// 写数据握手完成,等待写入完成后发送响应
|
||||
// 向设备发出一次写请求,WREADY 在一个周期后拉低
|
||||
WREADY := false.B
|
||||
write := false.B
|
||||
state := AXI4LiteStates.WriteResp
|
||||
BVALID := true.B
|
||||
state := AXI4LiteStates.WriteResp
|
||||
}
|
||||
|
||||
is(AXI4LiteStates.WriteResp) {
|
||||
// 等待写响应握手
|
||||
// 等待主机对写响应握手
|
||||
when(io.channels.write_response_channel.BREADY) {
|
||||
// 写响应握手完成
|
||||
BVALID := false.B
|
||||
state := AXI4LiteStates.Idle
|
||||
}
|
||||
@@ -281,55 +277,48 @@ class AXI4LiteMaster(addrWidth: Int, dataWidth: Int) extends Module {
|
||||
val BREADY = RegInit(false.B)
|
||||
io.channels.write_response_channel.BREADY := BREADY
|
||||
//lab4(BUS)
|
||||
// 清零valid信号(如果不是刚刚被置1)
|
||||
when(read_valid) {
|
||||
read_valid := false.B
|
||||
}
|
||||
when(write_valid) {
|
||||
write_valid := false.B
|
||||
}
|
||||
// read_valid / write_valid 只拉高一个周期,在switch之前清零以便switch可以覆盖
|
||||
when(read_valid) { read_valid := false.B }
|
||||
when(write_valid) { write_valid := false.B }
|
||||
|
||||
switch(state) {
|
||||
is(AXI4LiteStates.Idle) {
|
||||
// 默认状态:所有控制信号为低
|
||||
ARVALID := false.B
|
||||
RREADY := false.B
|
||||
AWVALID := false.B
|
||||
WVALID := false.B
|
||||
BREADY := false.B
|
||||
|
||||
// 检测读请求
|
||||
when(io.bundle.read) {
|
||||
state := AXI4LiteStates.ReadAddr
|
||||
// 发起读事务
|
||||
addr := io.bundle.address
|
||||
state := AXI4LiteStates.ReadAddr
|
||||
ARVALID := true.B
|
||||
}.elsewhen(io.bundle.write) {
|
||||
// 检测写请求
|
||||
state := AXI4LiteStates.WriteAddr
|
||||
// 发起写事务
|
||||
addr := io.bundle.address
|
||||
write_data := io.bundle.write_data
|
||||
write_strobe := io.bundle.write_strobe
|
||||
state := AXI4LiteStates.WriteAddr
|
||||
AWVALID := true.B
|
||||
}
|
||||
}
|
||||
|
||||
is(AXI4LiteStates.ReadAddr) {
|
||||
// 发送读地址,等待从机响应
|
||||
// 发送读地址,直到从机准备好
|
||||
ARVALID := true.B
|
||||
io.channels.read_address_channel.ARADDR := addr
|
||||
when(io.channels.read_address_channel.ARREADY) {
|
||||
// 读地址握手完成
|
||||
ARVALID := false.B
|
||||
state := AXI4LiteStates.ReadData
|
||||
RREADY := true.B
|
||||
state := AXI4LiteStates.ReadData
|
||||
}
|
||||
}
|
||||
|
||||
is(AXI4LiteStates.ReadData) {
|
||||
// 等待读数据,保持RREADY为高
|
||||
// 保持 RREADY 高,等待从机 RVALID
|
||||
RREADY := true.B
|
||||
when(io.channels.read_data_channel.RVALID) {
|
||||
// 读数据握手完成
|
||||
read_data := io.channels.read_data_channel.RDATA
|
||||
RREADY := false.B
|
||||
read_valid := true.B
|
||||
@@ -338,33 +327,32 @@ class AXI4LiteMaster(addrWidth: Int, dataWidth: Int) extends Module {
|
||||
}
|
||||
|
||||
is(AXI4LiteStates.WriteAddr) {
|
||||
// 发送写地址,等待从机响应
|
||||
// 发送写地址,直到从机准备好
|
||||
AWVALID := true.B
|
||||
io.channels.write_address_channel.AWADDR := addr
|
||||
when(io.channels.write_address_channel.AWREADY) {
|
||||
// 写地址握手完成
|
||||
AWVALID := false.B
|
||||
state := AXI4LiteStates.WriteData
|
||||
WVALID := true.B
|
||||
state := AXI4LiteStates.WriteData
|
||||
}
|
||||
}
|
||||
|
||||
is(AXI4LiteStates.WriteData) {
|
||||
// 发送写数据,保持WVALID为高
|
||||
// 发送写数据,直到从机接受
|
||||
WVALID := true.B
|
||||
io.channels.write_data_channel.WDATA := write_data
|
||||
io.channels.write_data_channel.WSTRB := write_strobe.asUInt
|
||||
when(io.channels.write_data_channel.WREADY) {
|
||||
// 写数据握手完成
|
||||
WVALID := false.B
|
||||
state := AXI4LiteStates.WriteResp
|
||||
BREADY := true.B
|
||||
state := AXI4LiteStates.WriteResp
|
||||
}
|
||||
}
|
||||
|
||||
is(AXI4LiteStates.WriteResp) {
|
||||
// 等待写响应,保持BREADY为高
|
||||
// 等待从机写响应
|
||||
BREADY := true.B
|
||||
when(io.channels.write_response_channel.BVALID) {
|
||||
// 写响应握手完成
|
||||
BREADY := false.B
|
||||
write_valid := true.B
|
||||
state := AXI4LiteStates.Idle
|
||||
|
||||
Reference in New Issue
Block a user