Commit 277c94d2 authored by Yuxiao Mao's avatar Yuxiao Mao
Browse files

Merge branch 'dev': fix crossing, sim Verilator ok, on board tilelink read write ok

parents ef4ee821 f894d5e6
......@@ -53,3 +53,7 @@ But the verilator simulation works well with the same config (RehadHarnessConfig
```
* INFO: Interrupt now has num 0 in interrupt Map, how to change it's number?
* TODO: `clockdiv` node take `clockNode` from `pbus`, and create auto clock in signal, this is not necessary. Is that possible to just use implicit clock?
* INFO: Access to `rehad_slow_detetion` via tilelink is async (D channel valid is set when A channel valid is receive)
......@@ -14,5 +14,30 @@
## Generate verilog
* Go to `Chipyard/sims/verilator` do `make SUB_PROJECT=rehad verilog`
* Go to `Chipyard/sims/verilator` do `make verilog`
## Implement on a Xilinx ML605 Evaluation Board FPGA
* From repository `Chipyard/sims/verilator/generated-src/$dir`, copy the following files:
* `$dir.harness.v`
* `$dir.top.v`
* `$dir.top.mem.v`
* `plusarg_reader.v`
* `ClockDivider2.v`
* From repository `rehad/board`, copy the following files:
* `ipcore/clkwiz_200_50.v`
* If use on board BlockRAM to simulate DRAM (the only choice for now)
* `BoardTop_bram.v` (this is the actual Top file)
* `bram/bram_axi4.v` (only support RV32)
* If simulation (attention, behavial simulation is not well supported for this project)
* `tbv_BoardTop_bram.v`
* If implementation
* `ml605.ucf`
* Manage memory content with [rehad-chipyard-rom](https://gitlab.laas.fr/ymao/rehad-chipyard-rom)
* Do `make` to generate `memX.hex`, init files for `rehad/board/bram/bram_axi4.v`. Place them in a repository named `input/`.
* Add those files to a Xilinx ISE project
* In synthesize Process Properties, set `-keep_hierarchy=YES` (to avoid xilinx synthesis tools error)
* Run and generate bitstream
......@@ -168,8 +168,7 @@ module BoardTop_bram
clkwiz_200_50 clkgen (
.CLK_IN200_P(hw_clk200m_p),
.CLK_IN200_N(hw_clk200m_n),
.CLK_OUT50(clock),
.RESET(hw_reset)
.CLK_OUT50(clock)
);
// Sync reset
......
......@@ -64,15 +64,13 @@
`timescale 1ps/1ps
(* CORE_GENERATION_INFO = "clkwiz_200_50,clk_wiz_v3_3,{component_name=clkwiz_200_50,use_phase_alignment=true,use_min_o_jitter=false,use_max_i_jitter=false,use_dyn_phase_shift=false,use_inclk_switchover=false,use_dyn_reconfig=false,feedback_source=FDBK_AUTO,primtype_sel=MMCM_ADV,num_out_clk=1,clkin1_period=5.000,clkin2_period=10.0,use_power_down=false,use_reset=true,use_locked=false,use_inclk_stopped=false,use_status=false,use_freeze=false,use_clk_valid=false,feedback_type=SINGLE,clock_mgr_type=MANUAL,manual_override=false}" *)
(* CORE_GENERATION_INFO = "clkwiz_200_50,clk_wiz_v3_3,{component_name=clkwiz_200_50,use_phase_alignment=true,use_min_o_jitter=false,use_max_i_jitter=false,use_dyn_phase_shift=false,use_inclk_switchover=false,use_dyn_reconfig=false,feedback_source=FDBK_AUTO,primtype_sel=MMCM_ADV,num_out_clk=1,clkin1_period=5.000,clkin2_period=10.0,use_power_down=false,use_reset=false,use_locked=false,use_inclk_stopped=false,use_status=false,use_freeze=false,use_clk_valid=false,feedback_type=SINGLE,clock_mgr_type=MANUAL,manual_override=false}" *)
module clkwiz_200_50
(// Clock in ports
input CLK_IN200_P,
input CLK_IN200_N,
// Clock out ports
output CLK_OUT50,
// Status and control signals
input RESET
output CLK_OUT50
);
// Input buffering
......@@ -163,7 +161,7 @@ module clkwiz_200_50
.CLKINSTOPPED (clkinstopped_unused),
.CLKFBSTOPPED (clkfbstopped_unused),
.PWRDWN (1'b0),
.RST (RESET));
.RST (1'b0));
// Output buffering
//-----------------------------------
......
......@@ -85,12 +85,15 @@ index 0000000..96023c0
+../../../../../rehad/chipyard/generators/chipyard/src/main/scala/config/RehadConfigs.scala
\ No newline at end of file
diff --git a/variables.mk b/variables.mk
index 4d49d5f..c258a54 100644
index 4d49d5f..1617996 100644
--- a/variables.mk
+++ b/variables.mk
@@ -27,12 +27,24 @@
@@ -25,14 +25,26 @@
# - make it so that you only change 1 param to change most or all of them!
# - mainly intended for quick developer setup for common flags
#########################################################################################
SUB_PROJECT ?= chipyard
-SUB_PROJECT ?= chipyard
+SUB_PROJECT ?= rehad
+# for Rehad dev
+ifeq ($(SUB_PROJECT),rehad)
......@@ -110,7 +113,7 @@ index 4d49d5f..c258a54 100644
VLOG_MODEL ?= TestHarness
MODEL_PACKAGE ?= $(SBT_PROJECT)
- CONFIG ?= RocketConfig
+ CONFIG ?= RehadHarnessConfig2
+ CONFIG ?= RehadHarnessConfig
CONFIG_PACKAGE ?= $(SBT_PROJECT)
GENERATOR_PACKAGE ?= $(SBT_PROJECT)
TB ?= TestDriver
......@@ -8,6 +8,7 @@ import rehad._
// --------------
class RehadConfig extends Config(
new WithRehad ++
// chipyard.iobinders apply mostly to chipyard.TestHarness, so it's unuseful to add them here
new rehad.WithRehadBootROM ++ // use custom simplified bootrom
new chipyard.config.WithUART ++ // add a UART
......@@ -33,7 +34,3 @@ class RehadHarnessConfig extends Config(
new testchipip.WithTSI ++
new chipyard.config.WithBootROM ++
new RehadConfig)
class RehadHarnessConfig2 extends Config(
new WithRehad ++
new RehadHarnessConfig)
......@@ -2,10 +2,10 @@ package rehad
import chisel3._
import chisel3.experimental.chiselName
import freechips.rocketchip.config.{Parameters}
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.interrupts._
import freechips.rocketchip.prci.{ClockDivider, ClockSinkDomain}
import freechips.rocketchip.prci.ClockSinkDomain
import freechips.rocketchip.regmapper.{RegField, RegFieldDesc}
import freechips.rocketchip.tile.{RehadCoreIO}
import freechips.rocketchip.tilelink._
......@@ -88,7 +88,7 @@ class RehadTopModuleImp(outer: RehadTopModule, params: RehadParams)
detection.clock := slow.clock
detection.reset := slow.reset
val par0 = RehadUtil.seq2par(params.clockDiv, io.tiles(0))
val par0 = RehadSync.seq2par(params.clockDiv, io.tiles(0))
// Registered at slow side
withClock(slow.clock) {
val par0reg = RegNext(par0)
......@@ -98,7 +98,6 @@ class RehadTopModuleImp(outer: RehadTopModule, params: RehadParams)
class RehadTopModule(params: RehadParams, beatBytes: Int)(implicit p: Parameters)
extends LazyModule
with HasClockDomainCrossing
{
lazy val module = new RehadTopModuleImp(this, params)
......@@ -106,23 +105,11 @@ class RehadTopModule(params: RehadParams, beatBytes: Int)(implicit p: Parameters
val rehad_slow_detection = LazyModule(new RehadSlowDetection(params, beatBytes))
// Clock divider and slow clock domain
val clockdiv = LazyModule(new ClockDivider(params.clockDiv))
val clockdiv = LazyModule(new RehadClockDivider(params.clockDiv))
val rehad_slow_domain = LazyModule(new ClockSinkDomain(take = None))
rehad_slow_domain.clockNode := clockdiv.node
// TileLink with crossing
val node = TLInwardCrossingHelper("rehadXnode", rehad_slow_domain, rehad_slow_detection.node)(RationalCrossing(FastToSlow))
val intnode = IntOutwardCrossingHelper("rehadXint", rehad_slow_domain, rehad_slow_detection.intnode)(RationalCrossing(FastToSlow))
}
object RehadUtil {
// Sequential to parallel logic, with most recent signal (input) at Vec(0)
def seq2par[T <: Data](clockDiv: Int, gen: T) : Vec[T] = {
val par = Reg(Vec(clockDiv, chiselTypeOf(gen)))
par.foldLeft(gen) { case (i, next) => {
next := i
next
}}
par
}
val node = TLInwardCrossingHelper("rehadXnode", rehad_slow_domain, rehad_slow_detection.node)(RationalCrossing(SlowToFast))
val intnode = IntOutwardCrossingHelper("rehadXint", rehad_slow_domain, rehad_slow_detection.intnode)(RationalCrossing(SlowToFast))
}
package rehad
import chisel3._
import chisel3.util.{isPow2, log2Ceil}
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp}
import freechips.rocketchip.prci.{ClockAdapterNode}
import freechips.rocketchip.util.{Pow2ClockDivider, ShiftRegInit}
// Adapt from rocket-chip.prci.ClockDivider
// Fix: param (x) to log2(x)
// Fix: Reset is async for the slow domain
class RehadClockDivider(div: Int)(implicit p: Parameters) extends LazyModule {
require(isPow2(div))
val node = ClockAdapterNode(
sourceFn = { case src => src.copy(give = src.give.map(x => x.copy(freqMHz = x.freqMHz / 2))) },
sinkFn = { case snk => snk.copy(take = snk.take.map(x => x.copy(freqMHz = x.freqMHz * 2))) })
lazy val module = new LazyModuleImp(this) {
(node.in zip node.out).foreach { case ((in, _), (out, _)) =>
val div_clock: Clock = Pow2ClockDivider(in.clock, log2Ceil(div))
out.clock := div_clock
out.reset := withClockAndReset(out.clock, in.reset.asAsyncReset) {
ShiftRegInit(in = false.B, n = 2, init = true.B, name = Some("slow_reset_pipe"))
}
}
}
}
object RehadSync {
// Sequential to parallel logic, with most recent signal (input) at Vec(0)
def seq2par[T <: Data](clockDiv: Int, gen: T) : Vec[T] = {
val par = Reg(Vec(clockDiv, chiselTypeOf(gen)))
par.foldLeft(gen) { case (i, next) => {
next := i
next
}}
par
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment