connect testharness components via member functions (#236)
to prevent code duplication for new testbenches
This commit is contained in:
		
				
					committed by
					
						 Andrew Waterman
						Andrew Waterman
					
				
			
			
				
	
			
			
			
						parent
						
							08089f695d
						
					
				
				
					commit
					4a7972be31
				
			| @@ -2,8 +2,7 @@ package junctions | |||||||
| import Chisel._ | import Chisel._ | ||||||
| import cde.{Parameters} | import cde.{Parameters} | ||||||
|  |  | ||||||
| class JtagIO(drvTdo : Boolean = false) extends Bundle { | class JTAGIO(drvTdo: Boolean = false) extends Bundle { | ||||||
|  |  | ||||||
|   val TCK = Clock(OUTPUT) |   val TCK = Clock(OUTPUT) | ||||||
|   val TMS = Bool(OUTPUT) |   val TMS = Bool(OUTPUT) | ||||||
|   val TDI = Bool(OUTPUT) |   val TDI = Bool(OUTPUT) | ||||||
| @@ -11,6 +10,5 @@ class JtagIO(drvTdo : Boolean = false) extends Bundle { | |||||||
|   val TRST = Bool(OUTPUT) |   val TRST = Bool(OUTPUT) | ||||||
|  |  | ||||||
|   val DRV_TDO = if (drvTdo) Some(Bool(INPUT)) else None |   val DRV_TDO = if (drvTdo) Some(Bool(INPUT)) else None | ||||||
|   override def cloneType = new JtagIO(drvTdo).asInstanceOf[this.type] |   override def cloneType = new JTAGIO(drvTdo).asInstanceOf[this.type] | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -39,7 +39,7 @@ class JtagDTMWithSync(implicit val p: Parameters) extends Module { | |||||||
|  |  | ||||||
|   val io = new Bundle { |   val io = new Bundle { | ||||||
|  |  | ||||||
|     val jtag = new JtagIO(true).flip() |     val jtag = new JTAGIO(true).flip() | ||||||
|     val debug = new DebugBusIO()(p) |     val debug = new DebugBusIO()(p) | ||||||
|  |  | ||||||
|   } |   } | ||||||
| @@ -105,7 +105,7 @@ class JtagDTMWithSync(implicit val p: Parameters) extends Module { | |||||||
| class DebugTransportModuleJtag(reqSize : Int, respSize : Int)(implicit val p: Parameters)  extends BlackBox { | class DebugTransportModuleJtag(reqSize : Int, respSize : Int)(implicit val p: Parameters)  extends BlackBox { | ||||||
|  |  | ||||||
|   val io = new Bundle { |   val io = new Bundle { | ||||||
|     val jtag = new JtagIO(true).flip() |     val jtag = new JTAGIO(true).flip() | ||||||
|  |  | ||||||
|     val dtm_req = new DecoupledIO(UInt(width = reqSize)) |     val dtm_req = new DecoupledIO(UInt(width = reqSize)) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -96,8 +96,8 @@ class TopIO(implicit p: Parameters) extends BasicTopIO()(p) { | |||||||
|   val mmio_tl  = Vec(p(NExtMMIOTLChannels),  new ClientUncachedTileLinkIO()(outermostMMIOParams)) |   val mmio_tl  = Vec(p(NExtMMIOTLChannels),  new ClientUncachedTileLinkIO()(outermostMMIOParams)) | ||||||
|   val debug_clk = (p(AsyncDebugBus) && !p(IncludeJtagDTM)).option(Clock(INPUT)) |   val debug_clk = (p(AsyncDebugBus) && !p(IncludeJtagDTM)).option(Clock(INPUT)) | ||||||
|   val debug_rst = (p(AsyncDebugBus) && !p(IncludeJtagDTM)).option(Bool(INPUT)) |   val debug_rst = (p(AsyncDebugBus) && !p(IncludeJtagDTM)).option(Bool(INPUT)) | ||||||
|   val debug =     (!p(IncludeJtagDTM)).option(new DebugBusIO()(p).flip) |   val debug = (!p(IncludeJtagDTM)).option(new DebugBusIO()(p).flip) | ||||||
|   val jtag  =      p(IncludeJtagDTM).option(new JtagIO(true).flip) |   val jtag = p(IncludeJtagDTM).option(new JTAGIO(true).flip) | ||||||
|   val extra = p(ExtraTopPorts)(p) |   val extra = p(ExtraTopPorts)(p) | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -36,46 +36,17 @@ class TestHarness(implicit p: Parameters) extends Module { | |||||||
|       Module(new SimAXIMem(memSize / dut.io.mem_axi.size)).io.axi <> axi |       Module(new SimAXIMem(memSize / dut.io.mem_axi.size)).io.axi <> axi | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (p(IncludeJtagDTM)) { |   if (!p(IncludeJtagDTM)) { | ||||||
|     val jtag_vpi = Module (new JtagVpi) |  | ||||||
|     dut.io.jtag.get <> jtag_vpi.io.jtag |  | ||||||
|  |  | ||||||
|     // To be proper, |  | ||||||
|     // TRST should really be synchronized |  | ||||||
|     // with TCK. But this is a fairly |  | ||||||
|     // accurate representation of how |  | ||||||
|     // HW may drive this signal. |  | ||||||
|     // Neither OpenOCD nor JtagVPI drive TRST. |  | ||||||
|  |  | ||||||
|     dut.io.jtag.get.TRST := reset  |  | ||||||
|     jtag_vpi.io.enable := ~reset |  | ||||||
|     jtag_vpi.io.init_done := ~reset |  | ||||||
|  |  | ||||||
|     // Success is determined by the gdbserver |  | ||||||
|     // which is controlling this simulation. |  | ||||||
|     io.success := Bool(false) |  | ||||||
|   } |  | ||||||
|   else { |  | ||||||
|     val dtm = Module(new SimDTM) |  | ||||||
|     dut.io.debug.get <> dtm.io.debug |  | ||||||
|  |  | ||||||
|     // Todo: enable the usage of different clocks |     // Todo: enable the usage of different clocks | ||||||
|     // to test the synchronizer more aggressively. |     // to test the synchronizer more aggressively. | ||||||
|     val dtm_clock = clock |     val dtm_clock = clock | ||||||
|     val dtm_reset = reset |     val dtm_reset = reset | ||||||
|  |     if (dut.io.debug_clk.isDefined) dut.io.debug_clk.get := dtm_clock | ||||||
|     dtm.io.clk := dtm_clock |     if (dut.io.debug_rst.isDefined) dut.io.debug_rst.get := dtm_reset | ||||||
|     dtm.io.reset := dtm_reset |     val dtm = Module(new SimDTM).connect(dtm_clock, dtm_reset, dut.io.debug.get, | ||||||
|     if (dut.io.debug_clk.isDefined) |       dut.io.success, io.success) | ||||||
|       dut.io.debug_clk.get := dtm_clock |   } else { | ||||||
|     if (dut.io.debug_rst.isDefined) |     val jtag = Module(new JTAGVPI).connect(dut.io.jtag.get, reset, io.success) | ||||||
|       dut.io.debug_rst.get := dtm_reset |  | ||||||
|  |  | ||||||
|     io.success := dut.io.success.getOrElse(dtm.io.exit === 1) |  | ||||||
|     when (dtm.io.exit >= 2) { |  | ||||||
|       printf("*** FAILED *** (exit code = %d)\n", dtm.io.exit >> 1) |  | ||||||
|       stop(1) |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   for (bus_axi <- dut.io.bus_axi) { |   for (bus_axi <- dut.io.bus_axi) { | ||||||
| @@ -154,14 +125,44 @@ class SimDTM(implicit p: Parameters) extends BlackBox { | |||||||
|     val debug = new uncore.devices.DebugBusIO |     val debug = new uncore.devices.DebugBusIO | ||||||
|     val exit = UInt(OUTPUT, 32) |     val exit = UInt(OUTPUT, 32) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   def connect(tbclk: Clock, tbreset: Bool, dutio: uncore.devices.DebugBusIO, | ||||||
|  |       dutsuccess: Option[Bool], tbsuccess: Bool) = { | ||||||
|  |     io.clk := tbclk | ||||||
|  |     io.reset := tbreset | ||||||
|  |     dutio <> io.debug | ||||||
|  |  | ||||||
|  |     tbsuccess := dutsuccess.getOrElse(io.exit === 1) | ||||||
|  |     when (io.exit >= 2) { | ||||||
|  |       printf("*** FAILED *** (exit code = %d)\n", io.exit >> 1) | ||||||
|  |       stop(1) | ||||||
|  |     } | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | class JTAGVPI(implicit val p: Parameters) extends BlackBox { | ||||||
| class JtagVpi(implicit val p: Parameters) extends BlackBox { |  | ||||||
|  |  | ||||||
|   val io = new Bundle { |   val io = new Bundle { | ||||||
|     val jtag = new JtagIO(false) |     val jtag = new JTAGIO(false) | ||||||
|     val enable = Bool(INPUT) |     val enable = Bool(INPUT) | ||||||
|     val init_done = Bool(INPUT) |     val init_done = Bool(INPUT) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   def connect(dutio: JTAGIO, tbreset: Bool, tbsuccess: Bool) = { | ||||||
|  |     dutio <> io.jtag | ||||||
|  |  | ||||||
|  |     // To be proper, | ||||||
|  |     // TRST should really be synchronized | ||||||
|  |     // with TCK. But this is a fairly | ||||||
|  |     // accurate representation of how | ||||||
|  |     // HW may drive this signal. | ||||||
|  |     // Neither OpenOCD nor JtagVPI drive TRST. | ||||||
|  |  | ||||||
|  |     dutio.TRST := tbreset | ||||||
|  |     io.enable := ~tbreset | ||||||
|  |     io.init_done := ~tbreset | ||||||
|  |  | ||||||
|  |     // Success is determined by the gdbserver | ||||||
|  |     // which is controlling this simulation. | ||||||
|  |     tbsuccess := Bool(false) | ||||||
|  |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -5,13 +5,13 @@ | |||||||
| # Verilog sources | # Verilog sources | ||||||
|  |  | ||||||
| bb_vsrcs = $(base_dir)/vsrc/DebugTransportModuleJtag.v \ | bb_vsrcs = $(base_dir)/vsrc/DebugTransportModuleJtag.v \ | ||||||
| 	   $(base_dir)/vsrc/jtag_vpi.v \ | 	$(base_dir)/vsrc/jtag_vpi.v \ | ||||||
| 	   $(base_dir)/vsrc/AsyncMailbox.v | 	$(base_dir)/vsrc/AsyncMailbox.v | ||||||
|  |  | ||||||
| sim_vsrcs = \ | sim_vsrcs = \ | ||||||
| 	$(generated_dir)/$(MODEL).$(CONFIG).v \ | 	$(generated_dir)/$(MODEL).$(CONFIG).v \ | ||||||
| 	$(generated_dir)/consts.$(CONFIG).vh \ | 	$(generated_dir)/consts.$(CONFIG).vh \ | ||||||
|         $(base_dir)/vsrc/$(TB).v \ | 	$(base_dir)/vsrc/$(TB).v \ | ||||||
| 	$(base_dir)/vsrc/SimDTM.v \ | 	$(base_dir)/vsrc/SimDTM.v \ | ||||||
| 	$(bb_vsrcs) | 	$(bb_vsrcs) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -36,7 +36,7 @@ | |||||||
| `define CMD_SCAN_CHAIN_FLIP_TMS	3 | `define CMD_SCAN_CHAIN_FLIP_TMS	3 | ||||||
| `define CMD_STOP_SIMU		4 | `define CMD_STOP_SIMU		4 | ||||||
|  |  | ||||||
| module JtagVpi | module JTAGVPI | ||||||
| #(	parameter DEBUG_INFO = 0, | #(	parameter DEBUG_INFO = 0, | ||||||
| 	parameter TP = 1, | 	parameter TP = 1, | ||||||
| 	parameter TCK_HALF_PERIOD = 2,// 50, // Clock half period (Clock period = 100 ns => 10 MHz) | 	parameter TCK_HALF_PERIOD = 2,// 50, // Clock half period (Clock period = 100 ns => 10 MHz) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user