Initial commit
This commit is contained in:
parent
2feb5c5ba3
commit
361c36a6e8
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
/.bloop
|
||||
/.metals
|
||||
/.vscode
|
||||
/project
|
||||
/target
|
||||
/simWorkspace
|
||||
/output
|
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Public
|
||||
Copyright (c) 2025 15inTech(www.15zk.net)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
|
@ -1,2 +1,5 @@
|
||||
# Adaptive_Direct_Digital_Synthesis
|
||||
# 自适应直接信号合成器
|
||||
|
||||
[使用手册](https://wiki.15zk.net/zh/opensource/Adaptive_Direct_Digital_Synthesis/manual)
|
||||
|
||||
[应用案例: 使用IW-RFSOC-2T2R生成宽带信号]()
|
16
build.sbt
Normal file
16
build.sbt
Normal file
@ -0,0 +1,16 @@
|
||||
ThisBuild / version := "1.0"
|
||||
ThisBuild / scalaVersion := "2.13.14"
|
||||
ThisBuild / organization := "cn.tiferking"
|
||||
|
||||
val spinalVersion = "1.12.0"
|
||||
val spinalCore = "com.github.spinalhdl" %% "spinalhdl-core" % spinalVersion
|
||||
val spinalLib = "com.github.spinalhdl" %% "spinalhdl-lib" % spinalVersion
|
||||
val spinalIdslPlugin = compilerPlugin("com.github.spinalhdl" %% "spinalhdl-idsl-plugin" % spinalVersion)
|
||||
|
||||
lazy val root = (project in file("."))
|
||||
.settings(
|
||||
Compile / scalaSource := baseDirectory.value / "src",
|
||||
libraryDependencies ++= Seq(spinalCore, spinalLib, spinalIdslPlugin)
|
||||
)
|
||||
|
||||
fork := true
|
18
src/Config.scala
Normal file
18
src/Config.scala
Normal file
@ -0,0 +1,18 @@
|
||||
package project.config
|
||||
|
||||
import spinal.core._
|
||||
import spinal.core.sim._
|
||||
|
||||
object Config {
|
||||
def spinal = SpinalConfig(
|
||||
targetDirectory = "output",
|
||||
defaultConfigForClockDomains = ClockDomainConfig(
|
||||
resetActiveLevel = LOW,
|
||||
resetKind = SYNC,
|
||||
clockEdge = RISING
|
||||
),
|
||||
onlyStdLogicVectorAtTopLevelIo = true
|
||||
)
|
||||
|
||||
def sim = SimConfig.withConfig(spinal)
|
||||
}
|
297
src/adds/Adds.scala
Normal file
297
src/adds/Adds.scala
Normal file
@ -0,0 +1,297 @@
|
||||
package adds
|
||||
|
||||
import spinal.core._
|
||||
import spinal.lib._
|
||||
import spinal.lib.bus.amba4.axis._
|
||||
import spinal.lib.bus.amba4.axi.Axi4SpecRenamer
|
||||
import spinal.lib.bus.amba4.axis.Axi4Stream._
|
||||
import spinal.lib.bus.amba4.axilite._
|
||||
import spinal.lib.io._
|
||||
import project.config._
|
||||
|
||||
case class Adds(phaseCh: Int, portBit: Int, resolutionBit: Int, sampleBit: Int, dualport: Boolean = false, simulation: Boolean = false) extends Component {
|
||||
val sampleCount = Math.pow(2, sampleBit).toInt;
|
||||
val regBit = 32;
|
||||
|
||||
object Mode extends SpinalEnum(defaultEncoding = binarySequential) {
|
||||
val TONE, LFM, SFM, FMCW = newElement()
|
||||
}
|
||||
|
||||
val io = new Bundle {
|
||||
val AddsOut = master(Axi4Stream(Axi4StreamConfig(phaseCh * (portBit / 8))))
|
||||
val AddsOutQ = dualport generate master(Axi4Stream(Axi4StreamConfig(phaseCh * (portBit / 8))))
|
||||
val Cfg = slave(AxiLite4(10,32))
|
||||
|
||||
//Ports for simulations
|
||||
val Sim = simulation generate (out Bits(portBit bits))
|
||||
val SimQ = simulation generate (out Bits(portBit bits))
|
||||
}
|
||||
noIoPrefix();
|
||||
|
||||
Axi4SpecRenamer(io.AddsOut);
|
||||
AxiLite4SpecRenamer(io.Cfg);
|
||||
|
||||
val CfgClockDomain = ClockDomain.external("Cfg");
|
||||
|
||||
val CfgArea = new ClockingArea(CfgClockDomain) {
|
||||
val resetSoftCfg = Reg(Bool()) init(False);
|
||||
val enSoftCfg = Reg(Bool()) init(False);
|
||||
val modeWorkCfg = Reg(Mode()) init(Mode.TONE);
|
||||
val phaseCfg = Reg(UInt(32 bits)) init(0);
|
||||
val dphaseCfg = Reg(UInt(32 bits)) init(0);
|
||||
val ddphaseCfg = Reg(SInt(32 bits)) init(0);
|
||||
val reloadCfg = Reg(UInt(32 bits)) init(0);
|
||||
val thresholdCfg = Reg(UInt(32 bits)) init(0);
|
||||
val stepholdCfg = Reg(UInt(32 bits)) init(0);
|
||||
|
||||
val resetSoftReadbackX = Reg(Bool()) init(False) addTag(crossClockDomain);
|
||||
val resetSoftReadback = RegNext(resetSoftReadbackX);
|
||||
|
||||
when (resetSoftReadback) {
|
||||
//Soft reset handshake
|
||||
resetSoftCfg.clear();
|
||||
}
|
||||
|
||||
when (resetSoftCfg) {
|
||||
//Soft reset register, clear all
|
||||
enSoftCfg.clearAll();
|
||||
modeWorkCfg.clearAll();
|
||||
phaseCfg.clearAll();
|
||||
dphaseCfg.clearAll();
|
||||
ddphaseCfg.clearAll();
|
||||
reloadCfg.clearAll();
|
||||
thresholdCfg.clearAll();
|
||||
stepholdCfg.clearAll();
|
||||
}
|
||||
|
||||
val axiArea = new Area{
|
||||
// !simulation for fix the simulation master bug.
|
||||
val axiSlave = new AxiLite4SlaveFactory(io.Cfg, !simulation);
|
||||
axiSlave.readAndWrite(resetSoftCfg, 0x00, 0, "Soft reset");
|
||||
axiSlave.readAndWrite(enSoftCfg, 0x00, 1, "Soft enable");
|
||||
axiSlave.readAndWrite(modeWorkCfg, 0x00, 8, "Working mode");
|
||||
axiSlave.readAndWrite(phaseCfg, 0x04, 0, "Init phase");
|
||||
axiSlave.readAndWrite(dphaseCfg, 0x08, 0, "Init frequence");
|
||||
axiSlave.readAndWrite(ddphaseCfg, 0x0C, 0, "Init delt frequence");
|
||||
axiSlave.readAndWrite(reloadCfg, 0x10, 0, "Reload delay");
|
||||
axiSlave.readAndWrite(thresholdCfg, 0x14, 0, "Threshold for reload");
|
||||
axiSlave.readAndWrite(stepholdCfg, 0x18, 0, "Step hold for SFM");
|
||||
axiSlave.printDataModel();
|
||||
}
|
||||
}
|
||||
|
||||
//Reg cross clock domain
|
||||
val resetSoftX = RegNext(CfgArea.resetSoftCfg) init(False) addTag(crossClockDomain);
|
||||
val enSoftX = RegNext(CfgArea.enSoftCfg) init(False) addTag(crossClockDomain);
|
||||
val modeWorkX = RegNext(CfgArea.modeWorkCfg) init(Mode.TONE) addTag(crossClockDomain);
|
||||
val phaseX = RegNext(CfgArea.phaseCfg) init(0) addTag(crossClockDomain);
|
||||
val dphaseX = RegNext(CfgArea.dphaseCfg) init(0) addTag(crossClockDomain);
|
||||
val ddphaseX = RegNext(CfgArea.ddphaseCfg) init(0) addTag(crossClockDomain);
|
||||
val reloadX = RegNext(CfgArea.reloadCfg) init(0) addTag(crossClockDomain);
|
||||
val thresholdX = RegNext(CfgArea.thresholdCfg) init(0) addTag(crossClockDomain);
|
||||
val stepholdX = RegNext(CfgArea.stepholdCfg) init(0) addTag(crossClockDomain);
|
||||
|
||||
val resetSoft = RegNext(resetSoftX) init(False);
|
||||
val enSoft = RegNext(enSoftX) init(False);
|
||||
val modeWork = RegNext(modeWorkX) init(Mode.TONE);
|
||||
val phase = RegNext(phaseX) init(0);
|
||||
val dphase = RegNext(dphaseX) init(0);
|
||||
val ddphase = RegNext(ddphaseX) init(0);
|
||||
val reload = RegNext(reloadX) init(0);
|
||||
val threshold = RegNext(thresholdX) init(0);
|
||||
val stephold = RegNext(stepholdX) init(0);
|
||||
|
||||
//Soft reset handshake
|
||||
CfgArea.resetSoftReadbackX := resetSoft;
|
||||
|
||||
def sinTable = for(sampleIndex <- 0 until sampleCount) yield {
|
||||
val sinValue = Math.sin(2 * Math.PI * sampleIndex / sampleCount);
|
||||
S((sinValue * ((1 << resolutionBit) / 2 - 1)).toInt, resolutionBit bits);
|
||||
}
|
||||
|
||||
val sinROM = Mem(SInt(resolutionBit bits), initialContent = sinTable);
|
||||
|
||||
//Working register
|
||||
val phaseWork = Vec.fill(phaseCh)(Reg(UInt(regBit bits)) init(0));
|
||||
val dphaseWork = Vec.fill(phaseCh)(Reg(UInt(regBit bits)) init(0));
|
||||
val ddphaseWork = Reg(SInt(regBit bits)) init(0);
|
||||
|
||||
//Initialization procedure counter
|
||||
val cntInit = Counter(0 to phaseCh + 5);
|
||||
//Working register reload counter
|
||||
val cntReload = Counter(regBit bits);
|
||||
//Working register step hold counter
|
||||
val cntStep = Counter(regBit bits);
|
||||
//Reload event triggered by initialization procedure or self reload
|
||||
val triggerReload = Reg(Bool()) init(False);
|
||||
//Output buffer
|
||||
val buffOut = Reg(Bits(phaseCh * portBit bits)) init(0);
|
||||
//Output buffer for dual port
|
||||
val buffOutQ = simulation generate (Reg(Bits(phaseCh * portBit bits)) init(0));
|
||||
//Disable the first uncertain output of the buffer
|
||||
val buffFirst = Reg(Bool()) init(True);
|
||||
|
||||
when(!enSoft) {
|
||||
//Reset dds status and working register
|
||||
phaseWork.clearAll();
|
||||
dphaseWork.clearAll();
|
||||
ddphaseWork.clearAll();
|
||||
buffOut.clearAll();
|
||||
dualport generate buffOutQ.clearAll();
|
||||
io.AddsOut.valid := False;
|
||||
dualport generate (io.AddsOutQ.valid := False);
|
||||
cntInit.clear();
|
||||
cntReload.clear();
|
||||
triggerReload.clear();
|
||||
cntStep.clear();
|
||||
buffFirst.set();
|
||||
} elsewhen(triggerReload) {
|
||||
when(cntReload > reload || modeWork === Mode.FMCW) {
|
||||
cntReload.clear();
|
||||
triggerReload.clear();
|
||||
cntInit.clear();
|
||||
} otherwise {
|
||||
cntReload.increment();
|
||||
}
|
||||
io.AddsOut.valid := True;
|
||||
dualport generate (io.AddsOutQ.valid := True);
|
||||
buffOut := 0;
|
||||
dualport generate (buffOutQ := 0);
|
||||
buffFirst.set();
|
||||
} elsewhen(cntInit < cntInit.end) {
|
||||
when(modeWork === Mode.TONE) {
|
||||
ddphaseWork := 0;
|
||||
for(i <- 0 until phaseCh)
|
||||
{
|
||||
dphaseWork(i) := dphase;
|
||||
}
|
||||
} elsewhen(modeWork === Mode.LFM || modeWork === Mode.FMCW) {
|
||||
ddphaseWork := ddphase;
|
||||
dphaseWork(0) := dphase;
|
||||
for(i <- 1 until phaseCh)
|
||||
{
|
||||
dphaseWork(i) := (dphaseWork(i - 1).asSInt + ddphaseWork).asUInt;
|
||||
}
|
||||
} elsewhen(modeWork === Mode.SFM) {
|
||||
ddphaseWork := ddphase;
|
||||
for(i <- 0 until phaseCh)
|
||||
{
|
||||
dphaseWork(i) := dphase;
|
||||
}
|
||||
} otherwise {
|
||||
ddphaseWork := 0;
|
||||
for(i <- 0 until phaseCh)
|
||||
{
|
||||
dphaseWork(i) := dphase;
|
||||
}
|
||||
}
|
||||
|
||||
phaseWork(0) := phase;
|
||||
for(i <- 1 until phaseCh)
|
||||
{
|
||||
phaseWork(i) := (phaseWork(i - 1) + dphaseWork(i));
|
||||
}
|
||||
|
||||
io.AddsOut.valid := True;
|
||||
dualport generate (io.AddsOutQ.valid := True);
|
||||
buffOut := 0;
|
||||
dualport generate (buffOutQ := 0);
|
||||
cntInit.increment();
|
||||
cntReload.increment();
|
||||
cntStep.clear();
|
||||
buffFirst.set();
|
||||
|
||||
} otherwise {
|
||||
when(modeWork === Mode.TONE) {
|
||||
|
||||
ddphaseWork := 0;
|
||||
for(i <- 0 until phaseCh)
|
||||
{
|
||||
dphaseWork(i) := dphase;
|
||||
}
|
||||
|
||||
} elsewhen(modeWork === Mode.LFM || modeWork === Mode.FMCW) {
|
||||
|
||||
ddphaseWork := ddphase;
|
||||
for(i <- 0 until phaseCh)
|
||||
{
|
||||
dphaseWork(i) := (dphaseWork(i).asSInt + (ddphaseWork * phaseCh).trim((log2Up(phaseCh) + 2) bits)).asUInt;
|
||||
}
|
||||
|
||||
when((!ddphase.sign && dphaseWork(phaseCh - 1) > threshold) ||
|
||||
(ddphase.sign && dphaseWork(phaseCh - 1) < threshold)) {
|
||||
triggerReload := True;
|
||||
}
|
||||
|
||||
} elsewhen(modeWork === Mode.SFM) {
|
||||
|
||||
when(cntStep < stephold) {
|
||||
cntStep.increment();
|
||||
} elsewhen(cntStep === stephold) {
|
||||
cntStep.increment();
|
||||
for(i <- 0 until phaseCh)
|
||||
{
|
||||
dphaseWork(i) := (dphaseWork(i).asSInt + ddphaseWork + (ddphaseWork * S(i).resize(log2Up(phaseCh) + 1)).trim((log2Up(phaseCh) + 1) bits)).asUInt;
|
||||
}
|
||||
} otherwise {
|
||||
for(i <- 0 until phaseCh)
|
||||
{
|
||||
dphaseWork(i) := (dphaseWork(i).asSInt + (ddphaseWork * S(phaseCh - i -1).resize(log2Up(phaseCh) + 1)).trim((log2Up(phaseCh) + 1) bits)).asUInt;
|
||||
}
|
||||
cntStep.clear();
|
||||
}
|
||||
|
||||
ddphaseWork := ddphase;
|
||||
|
||||
when((!ddphase.sign && dphaseWork(phaseCh - 1) > threshold) ||
|
||||
(ddphase.sign && dphaseWork(phaseCh - 1) < threshold)) {
|
||||
triggerReload := True;
|
||||
}
|
||||
}
|
||||
|
||||
for(i <- 0 until phaseCh)
|
||||
{
|
||||
phaseWork(i) := phaseWork(i) + (dphaseWork(i) * phaseCh).trim((log2Up(phaseCh) + 1) bits);
|
||||
}
|
||||
cntReload.increment();
|
||||
io.AddsOut.valid := True;
|
||||
dualport generate (io.AddsOutQ.valid := True);
|
||||
when(buffFirst) {
|
||||
buffOut := 0;
|
||||
dualport generate (buffOutQ := 0);
|
||||
buffFirst.clear();
|
||||
} otherwise {
|
||||
for(i <- 0 until phaseCh)
|
||||
{
|
||||
buffOut(i * portBit, portBit bits) := sinROM.readSync(phaseWork(i).round(regBit - sampleBit)).asBits.resizeLeft(portBit);
|
||||
dualport generate (buffOutQ(i * portBit, portBit bits) := sinROM.readSync(phaseWork(i).round(regBit - sampleBit) + sampleCount / 4).asBits.resizeLeft(portBit));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Init phase reg
|
||||
|
||||
io.AddsOut.data := buffOut;
|
||||
dualport generate (io.AddsOutQ.data := buffOutQ);
|
||||
|
||||
val SimClockDomain = simulation generate ClockDomain.external("Sim");
|
||||
val clockSim = simulation generate Bool();
|
||||
simulation generate {
|
||||
clockSim := clockDomain.readClockWire;
|
||||
val SimArea = new ClockingArea(SimClockDomain) {
|
||||
val cntSim = Counter(0 to phaseCh);
|
||||
val clockIn = Bool() addTag(crossClockDomain);
|
||||
clockIn := clockSim;
|
||||
when(clockIn.rise()) {
|
||||
cntSim.clear();
|
||||
} otherwise {
|
||||
cntSim.increment();
|
||||
}
|
||||
io.Sim := io.AddsOut.data(portBit * cntSim.value, portBit bits);
|
||||
dualport generate (io.SimQ := buffOutQ(portBit * cntSim.value, portBit bits));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object GenAdds extends App {
|
||||
Config.spinal.generateVerilog(Adds(16, 16, 12, 12)).printPruned();
|
||||
}
|
95
src/adds/sim/AddsSim.scala
Normal file
95
src/adds/sim/AddsSim.scala
Normal file
@ -0,0 +1,95 @@
|
||||
package adds.sim
|
||||
|
||||
import spinal.core._
|
||||
import spinal.lib._
|
||||
import spinal.lib.bus.amba4.axis._
|
||||
import spinal.lib.bus.amba4.axi.Axi4SpecRenamer
|
||||
import spinal.lib.bus.amba4.axis.Axi4Stream._
|
||||
import spinal.lib.bus.amba4.axilite._
|
||||
import spinal.lib.io._
|
||||
import project.config._
|
||||
import spinal.core.sim._
|
||||
import spinal.lib.bus.amba4.axilite.sim._
|
||||
import adds._
|
||||
import scala.util.control._
|
||||
|
||||
object AddsSim extends App {
|
||||
Config.sim.withFstWave.compile(new Adds(16, 16, 12, 12, true, true)).doSim{ dut =>
|
||||
|
||||
dut.clockDomain.reset()
|
||||
dut.CfgClockDomain.reset()
|
||||
dut.CfgClockDomain.forkStimulus(250)
|
||||
dut.clockDomain.forkStimulus(160)
|
||||
dut.SimClockDomain.forkStimulus(10)
|
||||
dut.clockDomain.waitRisingEdge()
|
||||
dut.CfgClockDomain.waitRisingEdge()
|
||||
dut.SimClockDomain.waitRisingEdge()
|
||||
|
||||
val master = AxiLite4Master(dut.io.Cfg, dut.CfgClockDomain)
|
||||
// TONE
|
||||
master.reset();
|
||||
master.write(0x00, List(0x00.toByte, 0x00.toByte, 0x00.toByte, 0x00.toByte));
|
||||
master.write(0x04, List(0x00.toByte, 0x00.toByte, 0x00.toByte, 0x00.toByte));
|
||||
master.write(0x08, List(0xFF.toByte, 0xFF.toByte, 0xFF.toByte, 0x00.toByte));
|
||||
master.write(0x0C, List(0x00.toByte, 0x10.toByte, 0x00.toByte, 0x00.toByte));
|
||||
master.write(0x10, List(0x00.toByte, 0x00.toByte, 0x00.toByte, 0x01.toByte));
|
||||
master.write(0x14, List(0x00.toByte, 0x00.toByte, 0x00.toByte, 0x80.toByte));
|
||||
master.write(0x18, List(0x10.toByte, 0x00.toByte, 0x00.toByte, 0x00.toByte));
|
||||
master.write(0x00, List(0x02.toByte, 0x00.toByte, 0x00.toByte, 0x00.toByte));
|
||||
dut.io.AddsOut.ready #= true
|
||||
|
||||
dut.clockDomain.waitRisingEdge();
|
||||
dut.clockDomain.waitEdge(100000);
|
||||
|
||||
dut.clockDomain.waitRisingEdge();
|
||||
|
||||
// LFM
|
||||
master.reset();
|
||||
master.write(0x00, List(0x00.toByte, 0x00.toByte, 0x00.toByte, 0x00.toByte));
|
||||
master.write(0x04, List(0x00.toByte, 0x00.toByte, 0x00.toByte, 0x00.toByte));
|
||||
master.write(0x08, List(0xFF.toByte, 0xFF.toByte, 0xFF.toByte, 0x00.toByte));
|
||||
master.write(0x0C, List(0x00.toByte, 0x10.toByte, 0x00.toByte, 0x00.toByte));
|
||||
master.write(0x10, List(0x00.toByte, 0x00.toByte, 0x00.toByte, 0x01.toByte));
|
||||
master.write(0x14, List(0x00.toByte, 0x00.toByte, 0x00.toByte, 0x80.toByte));
|
||||
master.write(0x18, List(0x10.toByte, 0x00.toByte, 0x00.toByte, 0x00.toByte));
|
||||
master.write(0x00, List(0x02.toByte, 0x01.toByte, 0x00.toByte, 0x00.toByte));
|
||||
dut.io.AddsOut.ready #= true
|
||||
|
||||
dut.clockDomain.waitRisingEdge();
|
||||
dut.clockDomain.waitEdge(100000);
|
||||
|
||||
dut.clockDomain.waitRisingEdge();
|
||||
|
||||
// SFM
|
||||
master.reset();
|
||||
master.write(0x00, List(0x00.toByte, 0x00.toByte, 0x00.toByte, 0x00.toByte));
|
||||
master.write(0x04, List(0x00.toByte, 0x00.toByte, 0x00.toByte, 0x00.toByte));
|
||||
master.write(0x08, List(0xFF.toByte, 0xFF.toByte, 0xFF.toByte, 0x00.toByte));
|
||||
master.write(0x0C, List(0x00.toByte, 0x10.toByte, 0x00.toByte, 0x00.toByte));
|
||||
master.write(0x10, List(0x00.toByte, 0x00.toByte, 0x00.toByte, 0x01.toByte));
|
||||
master.write(0x14, List(0x00.toByte, 0x00.toByte, 0x00.toByte, 0x80.toByte));
|
||||
master.write(0x18, List(0x10.toByte, 0x00.toByte, 0x00.toByte, 0x00.toByte));
|
||||
master.write(0x00, List(0x02.toByte, 0x02.toByte, 0x00.toByte, 0x00.toByte));
|
||||
dut.io.AddsOut.ready #= true
|
||||
|
||||
dut.clockDomain.waitRisingEdge();
|
||||
dut.clockDomain.waitEdge(100000);
|
||||
|
||||
dut.clockDomain.waitRisingEdge();
|
||||
|
||||
// FMCW
|
||||
master.reset();
|
||||
master.write(0x00, List(0x00.toByte, 0x00.toByte, 0x00.toByte, 0x00.toByte));
|
||||
master.write(0x04, List(0x00.toByte, 0x00.toByte, 0x00.toByte, 0x00.toByte));
|
||||
master.write(0x08, List(0xFF.toByte, 0xFF.toByte, 0xFF.toByte, 0x00.toByte));
|
||||
master.write(0x0C, List(0x00.toByte, 0x10.toByte, 0x00.toByte, 0x00.toByte));
|
||||
master.write(0x10, List(0x00.toByte, 0x00.toByte, 0x00.toByte, 0x01.toByte));
|
||||
master.write(0x14, List(0x00.toByte, 0x00.toByte, 0x00.toByte, 0x80.toByte));
|
||||
master.write(0x18, List(0x10.toByte, 0x00.toByte, 0x00.toByte, 0x00.toByte));
|
||||
master.write(0x00, List(0x02.toByte, 0x03.toByte, 0x00.toByte, 0x00.toByte));
|
||||
dut.io.AddsOut.ready #= true
|
||||
|
||||
dut.clockDomain.waitRisingEdge();
|
||||
dut.clockDomain.waitEdge(100000);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user