From a8b3f365924f6824221d3b3fe628b26ffcae5eee Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Tue, 18 Jun 2024 14:14:52 +0100 Subject: [PATCH 1/2] soc/cores/cpu: Implement add_jtag method Implement add_jtag method for naxriscv, vexiiriscv and vexriscv_smp, which is the de facto way to add JTAG ports to pads on other CPUs. Signed-off-by: Jiaxun Yang --- litex/soc/cores/cpu/naxriscv/core.py | 8 ++++++++ litex/soc/cores/cpu/vexiiriscv/core.py | 8 ++++++++ litex/soc/cores/cpu/vexriscv_smp/core.py | 8 ++++++++ 3 files changed, 24 insertions(+) diff --git a/litex/soc/cores/cpu/naxriscv/core.py b/litex/soc/cores/cpu/naxriscv/core.py index 090ffceca..2535cd8cc 100755 --- a/litex/soc/cores/cpu/naxriscv/core.py +++ b/litex/soc/cores/cpu/naxriscv/core.py @@ -462,6 +462,14 @@ class NaxRiscv(CPU): self.soc_bus = soc.bus # FIXME: Save SoC Bus instance to retrieve the final mem layout on finalization. + def add_jtag(self, pads): + self.comb += [ + self.jtag_tms.eq(pads.tms), + self.jtag_clk.eq(pads.tck), + self.jtag_tdi.eq(pads.tdi), + pads.tdo.eq(self.jtag_tdo), + ] + def add_memory_buses(self, address_width, data_width): NaxRiscv.litedram_width = data_width nax_data_width = 64 diff --git a/litex/soc/cores/cpu/vexiiriscv/core.py b/litex/soc/cores/cpu/vexiiriscv/core.py index 93b941ce6..6d402ab45 100755 --- a/litex/soc/cores/cpu/vexiiriscv/core.py +++ b/litex/soc/cores/cpu/vexiiriscv/core.py @@ -527,6 +527,14 @@ class VexiiRiscv(CPU): i_mBus_rlast = mbus.r.last, ) + def add_jtag(self, pads): + self.comb += [ + self.jtag_tms.eq(pads.tms), + self.jtag_clk.eq(pads.tck), + self.jtag_tdi.eq(pads.tdi), + pads.tdo.eq(self.jtag_tdo), + ] + def do_finalize(self): assert hasattr(self, "reset_address") diff --git a/litex/soc/cores/cpu/vexriscv_smp/core.py b/litex/soc/cores/cpu/vexriscv_smp/core.py index f45bce1ab..2432e5f74 100755 --- a/litex/soc/cores/cpu/vexriscv_smp/core.py +++ b/litex/soc/cores/cpu/vexriscv_smp/core.py @@ -463,6 +463,14 @@ class VexRiscvSMP(CPU): add_synthesis_define(cluster_filename) platform.add_source(cluster_filename, "verilog") + def add_jtag(self, pads): + self.comb += [ + self.jtag_tms.eq(pads.tms), + self.jtag_clk.eq(pads.tck), + self.jtag_tdi.eq(pads.tdi), + pads.tdo.eq(self.jtag_tdo), + ] + def add_soc_components(self, soc): if self.variant == "linux": # Set UART/Timer0 CSRs to the ones used by OpenSBI. From 50c8ef07b6c312248697abc37b5486ee2a147644 Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Tue, 18 Jun 2024 14:18:28 +0100 Subject: [PATCH 2/2] jtagremote: Implement ntrst pin ntrst pin is critical to some JTAG taps to put tap into a known state. Implement it in jtagremote testbench with corresponding remote bitbang commands and hook it up in litex_sim. Signed-off-by: Jiaxun Yang --- .../sim/core/modules/jtagremote/jtagremote.c | 41 +++++++++++++------ litex/tools/litex_sim.py | 6 +-- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/litex/build/sim/core/modules/jtagremote/jtagremote.c b/litex/build/sim/core/modules/jtagremote/jtagremote.c index 1b0fa4e25..29b4df1e7 100644 --- a/litex/build/sim/core/modules/jtagremote/jtagremote.c +++ b/litex/build/sim/core/modules/jtagremote/jtagremote.c @@ -15,6 +15,7 @@ struct session_s { char *tdo; char *tck; char *tms; + char *ntrst; char *sys_clk; struct event *ev; char databuf[2048]; @@ -199,6 +200,7 @@ static int jtagremote_add_pads(void *sess, struct pad_list_s *plist) litex_sim_module_pads_get(pads, "tdi", (void**)&s->tdi); litex_sim_module_pads_get(pads, "tdo", (void**)&s->tdo); litex_sim_module_pads_get(pads, "tms", (void**)&s->tms); + litex_sim_module_pads_get(pads, "ntrst", (void**)&s->ntrst); } if(!strcmp(plist->name, "sys_clk")) @@ -227,19 +229,34 @@ static int jtagremote_tick(void *sess, uint64_t time_ps) { c = s->databuf[s->data_start]; - if((c >= '0') && (c <= '7')){ - *s->tck = ((c - '0') >> 2) & 1; - *s->tms = ((c - '0') >> 1) & 1; - *s->tdi = (c - '0') & 1; - } - if(c == 'R'){ - val = *s->tdo + '0'; - if(-1 == write(s->fd, &val, 1)) { - eprintf("Error writing on socket\n"); - ret = RC_ERROR; - goto out; - } + switch(c) { + case '0'...'7': + *s->tck = ((c - '0') >> 2) & 1; + *s->tms = ((c - '0') >> 1) & 1; + *s->tdi = (c - '0') & 1; + break; + case 'r': + case 's': + /* Deassert reset */ + *s->ntrst = 1; + break; + case 't': + case 'u': + /* Assert reset */ + *s->ntrst = 0; + break; + case 'R': + val = *s->tdo + '0'; + if(write(s->fd, &val, 1) == -1) { + eprintf("Error writing on socket\n"); + ret = RC_ERROR; + goto out; + } + break; + default: + break; } + s->data_start = (s->data_start + 1) % 2048; s->datalen--; } diff --git a/litex/tools/litex_sim.py b/litex/tools/litex_sim.py index 5a1cb0da8..ac0a28c38 100755 --- a/litex/tools/litex_sim.py +++ b/litex/tools/litex_sim.py @@ -135,6 +135,7 @@ _io = [ Subsignal("tms", Pins(1)), Subsignal("tdi", Pins(1)), Subsignal("tdo", Pins(1)), + Subsignal("ntrst", Pins(1)), ), # Video (VGA). @@ -277,10 +278,7 @@ class SimSoC(SoCCore): # JTAG ------------------------------------------------------------------------------------- if with_jtag: jtag_pads = platform.request("jtag") - self.comb += self.cpu.jtag_clk.eq(jtag_pads.tck) - self.comb += self.cpu.jtag_tms.eq(jtag_pads.tms) - self.comb += self.cpu.jtag_tdi.eq(jtag_pads.tdi) - self.comb += jtag_pads.tdo.eq(self.cpu.jtag_tdo) + self.cpu.add_jtag(jtag_pads) # SDCard ----------------------------------------------------------------------------------- if with_sdcard: