From b25a8c08f57230063dfbba47a545df6be725a582 Mon Sep 17 00:00:00 2001 From: cchr Date: Wed, 17 Jul 2024 16:25:50 +0200 Subject: [PATCH 01/24] Fix clock polarity and register reset --- api/scaffold/__init__.py | 79 +++ api/tests/__init__.py | 0 api/tests/test_swd.py | 59 +++ fpga-arch/Counter.v | 75 +++ fpga-arch/swd_module.v | 1062 ++++++++++++++++++++++++++++++++++++++ fpga-arch/system.vhd | 88 +++- 6 files changed, 1357 insertions(+), 6 deletions(-) create mode 100644 api/tests/__init__.py create mode 100644 api/tests/test_swd.py create mode 100644 fpga-arch/Counter.v create mode 100644 fpga-arch/swd_module.v diff --git a/api/scaffold/__init__.py b/api/scaffold/__init__.py index b90f88e..0f950a5 100644 --- a/api/scaffold/__init__.py +++ b/api/scaffold/__init__.py @@ -1605,6 +1605,64 @@ def glitch_count(self, value): self.reg_count.set(value) +# CCHR +class SWDStatus(Enum): + OK = 0 + WAIT = 1 + FAULT = 2 + ERROR = 3 + + +class SWD(Module): + """ + SWD peripheral of Scaffold. + """ + + __REG_STATUS_BIT_READY = 0 + + def __init__(self, parent): + """ + :param parent: The Scaffold instance owning the SWD module. + """ + super().__init__(parent, "/swd") + # Declare the signals + self.add_signals("swclk", "swd_in", "swd_out") + # Declare the registers + self.__addr_base = base = 0x0b00 + self.add_register("rdata", "rv", base) + self.add_register("wdata", "w", base + 4, reset=0x00) + self.add_register("status", "rv", base + 0x10) + self.add_register("cmd", "w", base + 0x20) + + def reset(self): + self.reg_cmd.write(0x80) + return self.status() + + def read(self, apndp, addr): + val = 0b0000_0100 | ((apndp & 0b1) << 3) | (addr & 0b11) + self.reg_cmd.write(val) + return (self.status(), self.rdata()) + + def write(self, apndp, addr, wdata): + val = 0b0000_0000 | ((apndp & 0b1) << 3) | (addr & 0b11) + self.reg_wdata.write(wdata & 0xff) + self.reg_wdata.write((wdata >> 8) & 0xff) + self.reg_wdata.write((wdata >> 16) & 0xff) + self.reg_wdata.write((wdata >> 24) & 0xff) + self.reg_cmd.write(val) + return self.status() + + def status(self): + return SWDStatus(int.from_bytes(self.reg_status.read(), 'little') & 0b11) + + def rdata(self): + return int.from_bytes(self.reg_rdata.read(), 'little') | \ + int.from_bytes(self.reg_rdata.read(), 'little') << 8 | \ + int.from_bytes(self.reg_rdata.read(), 'little') << 16 | \ + int.from_bytes(self.reg_rdata.read(), 'little') << 24 +# CCHR + + class IOMode(Enum): AUTO = 0 OPEN_DRAIN = 1 @@ -2202,6 +2260,13 @@ def connect( self.clocks.append(clock) self.__setattr__(f"clock{i}", clock) +# CCHR + # Declare the swd module + if self.version >= "0.9": + self.swd = swd = SWD(self) + self.__setattr__("swd", swd) +# CCHR + # Create the ISO7816 module self.iso7816 = ISO7816(self) @@ -2259,6 +2324,10 @@ def connect( self.add_mtxl_out(f"/chain{i}/event{j}") for i in range(len(self.clocks)): self.add_mtxl_out(f"/clock{i}/glitch") +# CCHR + if self.version >= "0.9": + self.add_mtxl_out("/swd/swd_in") +# CCHR # FPGA right matrix input signals # Update this section when adding new modules with outpus @@ -2290,6 +2359,11 @@ def connect( self.add_mtxr_in(f"/chain{i}/trigger") for i in range(len(self.clocks)): self.add_mtxr_in(f"/clock{i}/out") +# CCHR + if self.version >= "0.9": + self.add_mtxr_in("/swd/swclk") + self.add_mtxr_in("/swd/swd_out") +# CCHR # FPGA right matrix output signals self.add_mtxr_out("/io/a0") @@ -2355,3 +2429,8 @@ def reset_config(self, init_ios=False): i2c.reset_config() for spi in self.spis: spi.reset_registers() +# CCHR + if self.version >= "0.9": + self.swd.reset_registers() +# OHE I commented out #self.swd.reset() +# CCHR diff --git a/api/tests/__init__.py b/api/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/api/tests/test_swd.py b/api/tests/test_swd.py new file mode 100644 index 0000000..5346293 --- /dev/null +++ b/api/tests/test_swd.py @@ -0,0 +1,59 @@ +# This file is part of Scaffold +# +# Scaffold is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +# +# Copyright 2024 Ledger SAS + +# from scaffold import Scaffold, Pull + + +# def test_dut_connection_ok(): +# scaffold = Scaffold("/dev/ttyUSB3") +# swd = scaffold.swd +# swd.swclk >> scaffold.d0 +# swd.swd_out >> scaffold.d1 +# swd.swd_in << scaffold.d1 +# scaffold.d0.pull = Pull.UP +# scaffold.d1.pull = Pull.UP +# +# status = swd.reset() +# print(f"status after: {status}") + + +# def test_read(): +# scaffold = Scaffold("/dev/ttyUSB3") +# swd = scaffold.swd +# swd.swclk >> scaffold.d0 +# swd.swd_out >> scaffold.d1 +# swd.swd_in << scaffold.d1 +# scaffold.d0.pull = Pull.UP +# scaffold.d1.pull = Pull.UP +# +# (status, rdata) = swd.read(0, 0) +# print(f"status after: {status}") +# print(f"rdata: {hex(rdata)}") + + +# def test_write(): +# scaffold = Scaffold("/dev/ttyUSB3") +# swd = scaffold.swd +# swd.swclk >> scaffold.d0 +# swd.swd_out >> scaffold.d1 +# swd.swd_in << scaffold.d1 +# scaffold.d0.pull = Pull.UP +# scaffold.d1.pull = Pull.UP +# +# status = swd.write(0, 0, 0b11010) +# print(f"status after: {status}") diff --git a/fpga-arch/Counter.v b/fpga-arch/Counter.v new file mode 100644 index 0000000..fc51e0c --- /dev/null +++ b/fpga-arch/Counter.v @@ -0,0 +1,75 @@ + +`ifdef BSV_ASSIGNMENT_DELAY +`else + `define BSV_ASSIGNMENT_DELAY +`endif + +`ifdef BSV_POSITIVE_RESET + `define BSV_RESET_VALUE 1'b1 + `define BSV_RESET_EDGE posedge +`else + `define BSV_RESET_VALUE 1'b0 + `define BSV_RESET_EDGE negedge +`endif + + +`ifdef BSV_ASYNC_RESET + `define BSV_ARESET_EDGE_META or `BSV_RESET_EDGE RST +`else + `define BSV_ARESET_EDGE_META +`endif + + +// N -bit counter with load, set and 2 increment +module Counter(CLK, + RST, + Q_OUT, + DATA_A, ADDA, + DATA_B, ADDB, + DATA_C, SETC, + DATA_F, SETF); + + parameter width = 1; + parameter init = 0; + + input CLK; + input RST; + input [width - 1 : 0] DATA_A; + input ADDA; + input [width - 1 : 0] DATA_B; + input ADDB; + input [width - 1 : 0] DATA_C; + input SETC; + input [width - 1 : 0] DATA_F; + input SETF; + + output [width - 1 : 0] Q_OUT; + + + + reg [width - 1 : 0] q_state ; + + assign Q_OUT = q_state ; + + always@(posedge CLK `BSV_ARESET_EDGE_META) begin + if (RST == `BSV_RESET_VALUE) + q_state <= `BSV_ASSIGNMENT_DELAY init; + else + begin + if ( SETF ) + q_state <= `BSV_ASSIGNMENT_DELAY DATA_F ; + else + q_state <= `BSV_ASSIGNMENT_DELAY (SETC ? DATA_C : q_state ) + (ADDA ? DATA_A : {width {1'b0}}) + (ADDB ? DATA_B : {width {1'b0}} ) ; + end // else: !if(RST == `BSV_RESET_VALUE) + end // always@ (posedge CLK) + +`ifdef BSV_NO_INITIAL_BLOCKS +`else // not BSV_NO_INITIAL_BLOCKS + // synopsys translate_off + initial begin + q_state = {((width + 1)/2){2'b10}} ; + end + // synopsys translate_on +`endif // BSV_NO_INITIAL_BLOCKS + +endmodule diff --git a/fpga-arch/swd_module.v b/fpga-arch/swd_module.v new file mode 100644 index 0000000..edc592e --- /dev/null +++ b/fpga-arch/swd_module.v @@ -0,0 +1,1062 @@ +// +// Generated by Bluespec Compiler, version 2024.01-9-gc481d7f5 (build c481d7f5) +// +// On Wed Jul 17 16:12:33 CEST 2024 +// +// +// Ports: +// Name I/O size props +// reg_rdata O 8 reg +// reg_status O 8 reg +// swclk O 1 reg +// swd_out O 1 reg +// out_en O 1 reg +// CLK I 1 clock +// RST_N I 1 reset +// address I 16 unused +// write_data I 8 +// write I 1 +// read I 1 +// en_rdata I 1 +// en_wdata I 1 +// en_cmd I 1 +// en_status I 1 +// swd_in I 1 +// +// No combinational paths from inputs to outputs +// +// + +`ifdef BSV_ASSIGNMENT_DELAY +`else + `define BSV_ASSIGNMENT_DELAY +`endif + +`ifdef BSV_POSITIVE_RESET + `define BSV_RESET_VALUE 1'b1 + `define BSV_RESET_EDGE posedge +`else + `define BSV_RESET_VALUE 1'b0 + `define BSV_RESET_EDGE negedge +`endif + +module swd_module(CLK, + RST_N, + + address, + + write_data, + + write, + + read, + + en_rdata, + + en_wdata, + + en_cmd, + + en_status, + + reg_rdata, + + reg_status, + + swclk, + + swd_in, + + swd_out, + + out_en); + input CLK; + input RST_N; + + // action method bus_address + input [15 : 0] address; + + // action method bus_write_data + input [7 : 0] write_data; + + // action method bus_write + input write; + + // action method bus_read + input read; + + // action method bus_en_rdata + input en_rdata; + + // action method bus_en_wdata + input en_wdata; + + // action method bus_en_cmd + input en_cmd; + + // action method bus_en_status + input en_status; + + // value method bus_reg_rdata + output [7 : 0] reg_rdata; + + // value method bus_reg_status + output [7 : 0] reg_status; + + // value method pins_swclk + output swclk; + + // action method pins_swd_in + input swd_in; + + // value method pins_swd_out + output swd_out; + + // value method pins_out_en + output out_en; + + // signals for module outputs + wire [7 : 0] reg_rdata, reg_status; + wire out_en, swclk, swd_out; + + // inlined wires + wire swd_controller_request_in$whas, swd_controller_reset_in$whas; + + // register bus_reg_rdata + reg [7 : 0] bus_reg_rdata; + reg [7 : 0] bus_reg_rdata$D_IN; + wire bus_reg_rdata$EN; + + // register bus_reg_status + reg [7 : 0] bus_reg_status; + wire [7 : 0] bus_reg_status$D_IN; + wire bus_reg_status$EN; + + // register cmd + reg [8 : 0] cmd; + wire [8 : 0] cmd$D_IN; + wire cmd$EN; + + // register rdata + reg [31 : 0] rdata; + wire [31 : 0] rdata$D_IN; + wire rdata$EN; + + // register ready + reg ready; + wire ready$D_IN, ready$EN; + + // register reg_rdata_cnt + reg [1 : 0] reg_rdata_cnt; + wire [1 : 0] reg_rdata_cnt$D_IN; + wire reg_rdata_cnt$EN; + + // register state + reg [1 : 0] state; + reg [1 : 0] state$D_IN; + wire state$EN; + + // register status + reg [1 : 0] status; + wire [1 : 0] status$D_IN; + wire status$EN; + + // register swd_controller_ack + reg [2 : 0] swd_controller_ack; + wire [2 : 0] swd_controller_ack$D_IN; + wire swd_controller_ack$EN; + + // register swd_controller_cnt + reg [6 : 0] swd_controller_cnt; + reg [6 : 0] swd_controller_cnt$D_IN; + wire swd_controller_cnt$EN; + + // register swd_controller_data + reg [32 : 0] swd_controller_data; + reg [32 : 0] swd_controller_data$D_IN; + wire swd_controller_data$EN; + + // register swd_controller_out_en + reg swd_controller_out_en; + wire swd_controller_out_en$D_IN, swd_controller_out_en$EN; + + // register swd_controller_packet + reg [7 : 0] swd_controller_packet; + reg [7 : 0] swd_controller_packet$D_IN; + wire swd_controller_packet$EN; + + // register swd_controller_rnw + reg swd_controller_rnw; + wire swd_controller_rnw$D_IN, swd_controller_rnw$EN; + + // register swd_controller_state + reg [3 : 0] swd_controller_state; + reg [3 : 0] swd_controller_state$D_IN; + wire swd_controller_state$EN; + + // register swd_controller_status + reg [2 : 0] swd_controller_status; + wire [2 : 0] swd_controller_status$D_IN; + wire swd_controller_status$EN; + + // register swd_controller_swclk + reg swd_controller_swclk; + wire swd_controller_swclk$D_IN, swd_controller_swclk$EN; + + // register swd_controller_swd_out + reg swd_controller_swd_out; + reg swd_controller_swd_out$D_IN; + wire swd_controller_swd_out$EN; + + // register wdata + reg [31 : 0] wdata; + wire [31 : 0] wdata$D_IN; + wire wdata$EN; + + // ports of submodule swd_controller_prescaler_ctr + wire [7 : 0] swd_controller_prescaler_ctr$DATA_A, + swd_controller_prescaler_ctr$DATA_B, + swd_controller_prescaler_ctr$DATA_C, + swd_controller_prescaler_ctr$DATA_F, + swd_controller_prescaler_ctr$Q_OUT; + wire swd_controller_prescaler_ctr$ADDA, + swd_controller_prescaler_ctr$ADDB, + swd_controller_prescaler_ctr$SETC, + swd_controller_prescaler_ctr$SETF; + + // rule scheduling signals + wire WILL_FIRE_RL_do_bus_write, + WILL_FIRE_RL_do_idle, + WILL_FIRE_RL_do_reset, + WILL_FIRE_RL_do_rw; + + // inputs to muxes for submodule ports + reg [2 : 0] MUX_swd_controller_status$write_1__VAL_1; + wire [32 : 0] MUX_swd_controller_data$write_1__VAL_1, + MUX_swd_controller_data$write_1__VAL_2, + MUX_swd_controller_data$write_1__VAL_3; + wire [8 : 0] MUX_cmd$write_1__VAL_1; + wire [7 : 0] MUX_swd_controller_packet$write_1__VAL_2, + MUX_swd_controller_packet$write_1__VAL_3; + wire [6 : 0] MUX_swd_controller_cnt$write_1__VAL_2, + MUX_swd_controller_cnt$write_1__VAL_4, + MUX_swd_controller_cnt$write_1__VAL_5, + MUX_swd_controller_cnt$write_1__VAL_6; + wire [3 : 0] MUX_swd_controller_state$write_1__VAL_1, + MUX_swd_controller_state$write_1__VAL_3, + MUX_swd_controller_state$write_1__VAL_7; + wire [1 : 0] MUX_state$write_1__VAL_2; + wire MUX_cmd$write_1__SEL_1, + MUX_state$write_1__SEL_1, + MUX_swd_controller_cnt$write_1__PSEL_1, + MUX_swd_controller_cnt$write_1__PSEL_6, + MUX_swd_controller_cnt$write_1__SEL_1, + MUX_swd_controller_cnt$write_1__SEL_2, + MUX_swd_controller_cnt$write_1__SEL_3, + MUX_swd_controller_cnt$write_1__SEL_4, + MUX_swd_controller_cnt$write_1__SEL_5, + MUX_swd_controller_cnt$write_1__SEL_6, + MUX_swd_controller_data$write_1__SEL_1, + MUX_swd_controller_data$write_1__SEL_2, + MUX_swd_controller_data$write_1__SEL_3, + MUX_swd_controller_packet$write_1__SEL_2, + MUX_swd_controller_packet$write_1__SEL_3, + MUX_swd_controller_state$write_1__PSEL_4, + MUX_swd_controller_state$write_1__SEL_3, + MUX_swd_controller_state$write_1__SEL_4, + MUX_swd_controller_state$write_1__SEL_5, + MUX_swd_controller_state$write_1__SEL_6, + MUX_swd_controller_status$write_1__SEL_1, + MUX_swd_controller_swclk$write_1__SEL_1, + MUX_swd_controller_swclk$write_1__SEL_2, + MUX_swd_controller_swd_out$write_1__PSEL_4, + MUX_swd_controller_swd_out$write_1__SEL_2, + MUX_swd_controller_swd_out$write_1__SEL_3, + MUX_swd_controller_swd_out$write_1__SEL_4, + MUX_swd_controller_swd_out$write_1__VAL_2, + MUX_swd_controller_swd_out$write_1__VAL_3; + + // remaining internal signals + wire [15 : 0] _0xE79E__q2; + wire [6 : 0] i__h1357, x__h14817; + wire [1 : 0] cmd_BITS_1_TO_0__q1; + wire swd_controller_cnt_2_ULE_8___d35, + swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d307, + x__h1338, + x__h19311, + x__h19324, + x__h19326, + x__h20464, + x__h20477, + z__h23711, + z__h23718, + z__h23725, + z__h23732, + z__h23739, + z__h23746, + z__h23753, + z__h23760, + z__h23767, + z__h23774, + z__h23781, + z__h23788, + z__h23795, + z__h23802, + z__h23809, + z__h23816, + z__h23823, + z__h23830, + z__h23837, + z__h23844, + z__h23851, + z__h23858, + z__h23865, + z__h23872, + z__h23879, + z__h23886, + z__h23893, + z__h23900, + z__h23907, + z__h23914, + z__h34272, + z__h34279, + z__h34286, + z__h34293, + z__h34300, + z__h34307, + z__h34314, + z__h34321, + z__h34328, + z__h34335, + z__h34342, + z__h34349, + z__h34356, + z__h34363, + z__h34370, + z__h34377, + z__h34384, + z__h34391, + z__h34398, + z__h34405, + z__h34412, + z__h34419, + z__h34426, + z__h34433, + z__h34440, + z__h34447, + z__h34454, + z__h34461, + z__h34468, + z__h34475, + z__h34482; + + // value method bus_reg_rdata + assign reg_rdata = bus_reg_rdata ; + + // value method bus_reg_status + assign reg_status = bus_reg_status ; + + // value method pins_swclk + assign swclk = swd_controller_swclk ; + + // value method pins_swd_out + assign swd_out = swd_controller_swd_out ; + + // value method pins_out_en + assign out_en = swd_controller_out_en ; + + // submodule swd_controller_prescaler_ctr + Counter #(.width(32'd8), + .init(8'd99)) swd_controller_prescaler_ctr(.CLK(CLK), + .RST(RST_N), + .DATA_A(swd_controller_prescaler_ctr$DATA_A), + .DATA_B(swd_controller_prescaler_ctr$DATA_B), + .DATA_C(swd_controller_prescaler_ctr$DATA_C), + .DATA_F(swd_controller_prescaler_ctr$DATA_F), + .ADDA(swd_controller_prescaler_ctr$ADDA), + .ADDB(swd_controller_prescaler_ctr$ADDB), + .SETC(swd_controller_prescaler_ctr$SETC), + .SETF(swd_controller_prescaler_ctr$SETF), + .Q_OUT(swd_controller_prescaler_ctr$Q_OUT)); + + // rule RL_do_bus_write + assign WILL_FIRE_RL_do_bus_write = write && state == 2'd0 ; + + // rule RL_do_idle + assign WILL_FIRE_RL_do_idle = + swd_controller_state == 4'd0 && !swd_controller_status[2] && + state == 2'd0 && + !write && + cmd[8] ; + + // rule RL_do_reset + assign WILL_FIRE_RL_do_reset = + swd_controller_state == 4'd0 && !swd_controller_status[2] && + state == 2'd1 ; + + // rule RL_do_rw + assign WILL_FIRE_RL_do_rw = + swd_controller_state == 4'd0 && swd_controller_status[2] && + state == 2'd2 ; + + // inputs to muxes for submodule ports + assign MUX_cmd$write_1__SEL_1 = + WILL_FIRE_RL_do_bus_write && { en_wdata, en_cmd } == 2'b01 ; + assign MUX_state$write_1__SEL_1 = WILL_FIRE_RL_do_reset && ready ; + assign MUX_swd_controller_cnt$write_1__PSEL_1 = + swd_controller_state == 4'd7 || swd_controller_state == 4'd1 || + swd_controller_state == 4'd8 ; + assign MUX_swd_controller_cnt$write_1__SEL_1 = + MUX_swd_controller_cnt$write_1__PSEL_1 && + swd_controller_prescaler_ctr$Q_OUT == 8'd0 ; + assign MUX_swd_controller_cnt$write_1__SEL_2 = + swd_controller_state == 4'd4 && + swd_controller_prescaler_ctr$Q_OUT == 8'd1 ; + assign MUX_swd_controller_cnt$write_1__SEL_3 = + swd_controller_state == 4'd2 && + swd_controller_prescaler_ctr$Q_OUT == 8'd1 ; + assign MUX_swd_controller_cnt$write_1__SEL_4 = + swd_controller_state == 4'd0 && + (swd_controller_request_in$whas || + swd_controller_reset_in$whas) ; + assign MUX_swd_controller_cnt$write_1__SEL_5 = + swd_controller_state == 4'd3 && + (swd_controller_prescaler_ctr$Q_OUT == 8'd0 || + swd_controller_prescaler_ctr$Q_OUT == 8'd1 && + swd_controller_cnt == 7'd0 && + swd_controller_rnw) ; + assign MUX_swd_controller_cnt$write_1__PSEL_6 = + swd_controller_state == 4'd6 || swd_controller_state == 4'd5 ; + assign MUX_swd_controller_cnt$write_1__SEL_6 = + MUX_swd_controller_cnt$write_1__PSEL_6 && + (swd_controller_prescaler_ctr$Q_OUT == 8'd0 || + swd_controller_prescaler_ctr$Q_OUT == 8'd1 && + swd_controller_cnt == 7'd0) ; + assign MUX_swd_controller_data$write_1__SEL_1 = + swd_controller_state == 4'd5 && + swd_controller_prescaler_ctr$Q_OUT == 8'd0 ; + assign MUX_swd_controller_data$write_1__SEL_2 = + swd_controller_state == 4'd6 && + swd_controller_prescaler_ctr$Q_OUT == 8'd0 ; + assign MUX_swd_controller_data$write_1__SEL_3 = + WILL_FIRE_RL_do_idle && !cmd[7] && !cmd[2] ; + assign MUX_swd_controller_packet$write_1__SEL_2 = + WILL_FIRE_RL_do_idle && !cmd[7] ; + assign MUX_swd_controller_packet$write_1__SEL_3 = + swd_controller_state == 4'd1 && + swd_controller_prescaler_ctr$Q_OUT == 8'd0 && + swd_controller_cnt_2_ULE_8___d35 ; + assign MUX_swd_controller_state$write_1__SEL_3 = + swd_controller_state == 4'd3 && + swd_controller_prescaler_ctr$Q_OUT == 8'd1 && + swd_controller_cnt == 7'd0 ; + assign MUX_swd_controller_state$write_1__PSEL_4 = + swd_controller_state == 4'd7 || swd_controller_state == 4'd8 ; + assign MUX_swd_controller_state$write_1__SEL_4 = + MUX_swd_controller_state$write_1__PSEL_4 && + swd_controller_prescaler_ctr$Q_OUT == 8'd1 && + swd_controller_cnt == 7'd0 ; + assign MUX_swd_controller_state$write_1__SEL_5 = + swd_controller_state == 4'd1 && + swd_controller_prescaler_ctr$Q_OUT == 8'd1 && + swd_controller_cnt == 7'd0 ; + assign MUX_swd_controller_state$write_1__SEL_6 = + MUX_swd_controller_cnt$write_1__PSEL_6 && + swd_controller_prescaler_ctr$Q_OUT == 8'd1 && + swd_controller_cnt == 7'd0 ; + assign MUX_swd_controller_status$write_1__SEL_1 = + swd_controller_state == 4'd7 && + swd_controller_prescaler_ctr$Q_OUT == 8'd0 ; + assign MUX_swd_controller_swclk$write_1__SEL_1 = + swd_controller_state != 4'd0 && + (swd_controller_prescaler_ctr$Q_OUT == 8'd0 || + swd_controller_prescaler_ctr$Q_OUT == 8'd50) ; + assign MUX_swd_controller_swclk$write_1__SEL_2 = + swd_controller_state == 4'd0 && + !swd_controller_request_in$whas && + !swd_controller_reset_in$whas ; + assign MUX_swd_controller_swd_out$write_1__SEL_2 = + swd_controller_state == 4'd8 && + swd_controller_prescaler_ctr$Q_OUT == 8'd0 ; + assign MUX_swd_controller_swd_out$write_1__SEL_3 = + swd_controller_state == 4'd1 && + swd_controller_prescaler_ctr$Q_OUT == 8'd0 ; + assign MUX_swd_controller_swd_out$write_1__PSEL_4 = + swd_controller_state == 4'd4 || swd_controller_state == 4'd2 ; + assign MUX_swd_controller_swd_out$write_1__SEL_4 = + MUX_swd_controller_swd_out$write_1__PSEL_4 && + swd_controller_prescaler_ctr$Q_OUT == 8'd0 ; + assign MUX_cmd$write_1__VAL_1 = { 1'd1, write_data } ; + assign MUX_state$write_1__VAL_2 = cmd[7] ? 2'd1 : 2'd2 ; + assign MUX_swd_controller_cnt$write_1__VAL_2 = + (swd_controller_ack == 3'b100) ? 7'd33 : 7'd1 ; + assign MUX_swd_controller_cnt$write_1__VAL_4 = + swd_controller_request_in$whas ? 7'd10 : 7'd126 ; + assign MUX_swd_controller_cnt$write_1__VAL_5 = + (swd_controller_prescaler_ctr$Q_OUT == 8'd0) ? + x__h14817 : + 7'd33 ; + assign MUX_swd_controller_cnt$write_1__VAL_6 = + (swd_controller_prescaler_ctr$Q_OUT == 8'd0) ? x__h14817 : 7'd1 ; + assign MUX_swd_controller_data$write_1__VAL_1 = + { swd_in, swd_controller_data[32:1] } ; + assign MUX_swd_controller_data$write_1__VAL_2 = + { 1'd0, swd_controller_data[32:1] } ; + assign MUX_swd_controller_data$write_1__VAL_3 = + { z__h23914 ^ wdata[7], + wdata[7:0], + wdata[15:8], + wdata[23:16], + wdata[31:24] } ; + assign MUX_swd_controller_packet$write_1__VAL_2 = + { 1'd1, cmd[3:0], cmd[2] ? x__h19311 : x__h20464, 2'd1 } ; + assign MUX_swd_controller_packet$write_1__VAL_3 = + { swd_controller_packet[6:0], 1'd0 } ; + assign MUX_swd_controller_state$write_1__VAL_1 = + (swd_controller_ack == 3'b100) ? 4'd6 : 4'd7 ; + assign MUX_swd_controller_state$write_1__VAL_3 = + swd_controller_rnw ? 4'd5 : 4'd4 ; + assign MUX_swd_controller_state$write_1__VAL_7 = + swd_controller_request_in$whas ? 4'd1 : 4'd8 ; + always@(swd_controller_ack) + begin + case (swd_controller_ack) + 3'b001: MUX_swd_controller_status$write_1__VAL_1 = 3'd6; + 3'b010: MUX_swd_controller_status$write_1__VAL_1 = 3'd5; + 3'b100: MUX_swd_controller_status$write_1__VAL_1 = swd_controller_ack; + default: MUX_swd_controller_status$write_1__VAL_1 = 3'd7; + endcase + end + assign MUX_swd_controller_swd_out$write_1__VAL_2 = + swd_controller_cnt > 7'd71 || swd_controller_cnt <= 7'd55 || + x__h1338 ; + assign MUX_swd_controller_swd_out$write_1__VAL_3 = + swd_controller_cnt_2_ULE_8___d35 && swd_controller_packet[7] ; + + // inlined wires + assign swd_controller_request_in$whas = + WILL_FIRE_RL_do_reset && ready || + WILL_FIRE_RL_do_idle && !cmd[7] ; + assign swd_controller_reset_in$whas = WILL_FIRE_RL_do_idle && cmd[7] ; + + // register bus_reg_rdata + always@(reg_rdata_cnt or rdata) + begin + case (reg_rdata_cnt) + 2'd0: bus_reg_rdata$D_IN = rdata[7:0]; + 2'd1: bus_reg_rdata$D_IN = rdata[15:8]; + 2'd2: bus_reg_rdata$D_IN = rdata[23:16]; + 2'd3: bus_reg_rdata$D_IN = rdata[31:24]; + endcase + end + assign bus_reg_rdata$EN = read && { en_rdata, en_status } == 2'b10 ; + + // register bus_reg_status + assign bus_reg_status$D_IN = { state == 2'd0, 5'b0, status } ; + assign bus_reg_status$EN = read && { en_rdata, en_status } == 2'b01 ; + + // register cmd + assign cmd$D_IN = MUX_cmd$write_1__SEL_1 ? MUX_cmd$write_1__VAL_1 : 9'd170 ; + assign cmd$EN = + WILL_FIRE_RL_do_bus_write && { en_wdata, en_cmd } == 2'b01 || + WILL_FIRE_RL_do_rw ; + + // register rdata + assign rdata$D_IN = + swd_controller_rnw ? + (swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d307 ? + 32'd0 : + swd_controller_data[31:0]) : + 32'd0 ; + assign rdata$EN = WILL_FIRE_RL_do_rw ; + + // register ready + assign ready$D_IN = swd_controller_state == 4'd0 ; + assign ready$EN = 1'd1 ; + + // register reg_rdata_cnt + assign reg_rdata_cnt$D_IN = reg_rdata_cnt + 2'd1 ; + assign reg_rdata_cnt$EN = read && { en_rdata, en_status } == 2'b10 ; + + // register state + always@(MUX_state$write_1__SEL_1 or + WILL_FIRE_RL_do_idle or + MUX_state$write_1__VAL_2 or WILL_FIRE_RL_do_rw) + begin + case (1'b1) // synopsys parallel_case + MUX_state$write_1__SEL_1: state$D_IN = 2'd2; + WILL_FIRE_RL_do_idle: state$D_IN = MUX_state$write_1__VAL_2; + WILL_FIRE_RL_do_rw: state$D_IN = 2'd0; + default: state$D_IN = 2'b10 /* unspecified value */ ; + endcase + end + assign state$EN = + WILL_FIRE_RL_do_reset && ready || WILL_FIRE_RL_do_idle || + WILL_FIRE_RL_do_rw ; + + // register status + assign status$D_IN = + swd_controller_rnw ? + (swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d307 ? + 2'd3 : + swd_controller_status[1:0]) : + swd_controller_status[1:0] ; + assign status$EN = WILL_FIRE_RL_do_rw ; + + // register swd_controller_ack + assign swd_controller_ack$D_IN = { swd_controller_ack[1:0], swd_in } ; + assign swd_controller_ack$EN = + swd_controller_state == 4'd3 && + swd_controller_prescaler_ctr$Q_OUT == 8'd0 ; + + // register swd_controller_cnt + always@(MUX_swd_controller_cnt$write_1__SEL_1 or + x__h14817 or + MUX_swd_controller_cnt$write_1__SEL_2 or + MUX_swd_controller_cnt$write_1__VAL_2 or + MUX_swd_controller_cnt$write_1__SEL_3 or + MUX_swd_controller_cnt$write_1__SEL_4 or + MUX_swd_controller_cnt$write_1__VAL_4 or + MUX_swd_controller_cnt$write_1__SEL_5 or + MUX_swd_controller_cnt$write_1__VAL_5 or + MUX_swd_controller_cnt$write_1__SEL_6 or + MUX_swd_controller_cnt$write_1__VAL_6) + begin + case (1'b1) // synopsys parallel_case + MUX_swd_controller_cnt$write_1__SEL_1: + swd_controller_cnt$D_IN = x__h14817; + MUX_swd_controller_cnt$write_1__SEL_2: + swd_controller_cnt$D_IN = MUX_swd_controller_cnt$write_1__VAL_2; + MUX_swd_controller_cnt$write_1__SEL_3: swd_controller_cnt$D_IN = 7'd3; + MUX_swd_controller_cnt$write_1__SEL_4: + swd_controller_cnt$D_IN = MUX_swd_controller_cnt$write_1__VAL_4; + MUX_swd_controller_cnt$write_1__SEL_5: + swd_controller_cnt$D_IN = MUX_swd_controller_cnt$write_1__VAL_5; + MUX_swd_controller_cnt$write_1__SEL_6: + swd_controller_cnt$D_IN = MUX_swd_controller_cnt$write_1__VAL_6; + default: swd_controller_cnt$D_IN = 7'b0101010 /* unspecified value */ ; + endcase + end + assign swd_controller_cnt$EN = + (swd_controller_state == 4'd7 || swd_controller_state == 4'd1 || + swd_controller_state == 4'd8) && + swd_controller_prescaler_ctr$Q_OUT == 8'd0 || + swd_controller_state == 4'd4 && + swd_controller_prescaler_ctr$Q_OUT == 8'd1 || + swd_controller_state == 4'd2 && + swd_controller_prescaler_ctr$Q_OUT == 8'd1 || + swd_controller_state == 4'd0 && + (swd_controller_request_in$whas || + swd_controller_reset_in$whas) || + MUX_swd_controller_cnt$write_1__SEL_5 || + (swd_controller_state == 4'd6 || swd_controller_state == 4'd5) && + (swd_controller_prescaler_ctr$Q_OUT == 8'd0 || + swd_controller_prescaler_ctr$Q_OUT == 8'd1 && + swd_controller_cnt == 7'd0) ; + + // register swd_controller_data + always@(MUX_swd_controller_data$write_1__SEL_1 or + MUX_swd_controller_data$write_1__VAL_1 or + MUX_swd_controller_data$write_1__SEL_2 or + MUX_swd_controller_data$write_1__VAL_2 or + MUX_swd_controller_data$write_1__SEL_3 or + MUX_swd_controller_data$write_1__VAL_3 or WILL_FIRE_RL_do_rw) + begin + case (1'b1) // synopsys parallel_case + MUX_swd_controller_data$write_1__SEL_1: + swd_controller_data$D_IN = MUX_swd_controller_data$write_1__VAL_1; + MUX_swd_controller_data$write_1__SEL_2: + swd_controller_data$D_IN = MUX_swd_controller_data$write_1__VAL_2; + MUX_swd_controller_data$write_1__SEL_3: + swd_controller_data$D_IN = MUX_swd_controller_data$write_1__VAL_3; + WILL_FIRE_RL_do_rw: swd_controller_data$D_IN = 33'd0; + default: swd_controller_data$D_IN = + 33'h0AAAAAAAA /* unspecified value */ ; + endcase + end + assign swd_controller_data$EN = + swd_controller_state == 4'd5 && + swd_controller_prescaler_ctr$Q_OUT == 8'd0 || + swd_controller_state == 4'd6 && + swd_controller_prescaler_ctr$Q_OUT == 8'd0 || + WILL_FIRE_RL_do_idle && !cmd[7] && !cmd[2] || + WILL_FIRE_RL_do_rw ; + + // register swd_controller_out_en + assign swd_controller_out_en$D_IN = + swd_controller_state == 4'd8 || swd_controller_state == 4'd1 || + swd_controller_state == 4'd6 ; + assign swd_controller_out_en$EN = 1'd1 ; + + // register swd_controller_packet + always@(MUX_state$write_1__SEL_1 or + MUX_swd_controller_packet$write_1__SEL_2 or + MUX_swd_controller_packet$write_1__VAL_2 or + MUX_swd_controller_packet$write_1__SEL_3 or + MUX_swd_controller_packet$write_1__VAL_3 or WILL_FIRE_RL_do_rw) + begin + case (1'b1) // synopsys parallel_case + MUX_state$write_1__SEL_1: swd_controller_packet$D_IN = 8'd165; + MUX_swd_controller_packet$write_1__SEL_2: + swd_controller_packet$D_IN = + MUX_swd_controller_packet$write_1__VAL_2; + MUX_swd_controller_packet$write_1__SEL_3: + swd_controller_packet$D_IN = + MUX_swd_controller_packet$write_1__VAL_3; + WILL_FIRE_RL_do_rw: swd_controller_packet$D_IN = 8'd0; + default: swd_controller_packet$D_IN = + 8'b10101010 /* unspecified value */ ; + endcase + end + assign swd_controller_packet$EN = + WILL_FIRE_RL_do_reset && ready || + WILL_FIRE_RL_do_idle && !cmd[7] || + swd_controller_state == 4'd1 && + swd_controller_prescaler_ctr$Q_OUT == 8'd0 && + swd_controller_cnt_2_ULE_8___d35 || + WILL_FIRE_RL_do_rw ; + + // register swd_controller_rnw + assign swd_controller_rnw$D_IN = MUX_state$write_1__SEL_1 || cmd[2] ; + assign swd_controller_rnw$EN = swd_controller_request_in$whas ; + + // register swd_controller_state + always@(MUX_swd_controller_cnt$write_1__SEL_2 or + MUX_swd_controller_state$write_1__VAL_1 or + MUX_swd_controller_cnt$write_1__SEL_3 or + MUX_swd_controller_state$write_1__SEL_3 or + MUX_swd_controller_state$write_1__VAL_3 or + MUX_swd_controller_state$write_1__SEL_4 or + MUX_swd_controller_state$write_1__SEL_5 or + MUX_swd_controller_state$write_1__SEL_6 or + MUX_swd_controller_cnt$write_1__SEL_4 or + MUX_swd_controller_state$write_1__VAL_7) + begin + case (1'b1) // synopsys parallel_case + MUX_swd_controller_cnt$write_1__SEL_2: + swd_controller_state$D_IN = MUX_swd_controller_state$write_1__VAL_1; + MUX_swd_controller_cnt$write_1__SEL_3: swd_controller_state$D_IN = 4'd3; + MUX_swd_controller_state$write_1__SEL_3: + swd_controller_state$D_IN = MUX_swd_controller_state$write_1__VAL_3; + MUX_swd_controller_state$write_1__SEL_4: + swd_controller_state$D_IN = 4'd0; + MUX_swd_controller_state$write_1__SEL_5: + swd_controller_state$D_IN = 4'd2; + MUX_swd_controller_state$write_1__SEL_6: + swd_controller_state$D_IN = 4'd7; + MUX_swd_controller_cnt$write_1__SEL_4: + swd_controller_state$D_IN = MUX_swd_controller_state$write_1__VAL_7; + default: swd_controller_state$D_IN = 4'b1010 /* unspecified value */ ; + endcase + end + assign swd_controller_state$EN = + swd_controller_state == 4'd4 && + swd_controller_prescaler_ctr$Q_OUT == 8'd1 || + swd_controller_state == 4'd2 && + swd_controller_prescaler_ctr$Q_OUT == 8'd1 || + swd_controller_state == 4'd3 && + swd_controller_prescaler_ctr$Q_OUT == 8'd1 && + swd_controller_cnt == 7'd0 || + (swd_controller_state == 4'd7 || swd_controller_state == 4'd8) && + swd_controller_prescaler_ctr$Q_OUT == 8'd1 && + swd_controller_cnt == 7'd0 || + swd_controller_state == 4'd1 && + swd_controller_prescaler_ctr$Q_OUT == 8'd1 && + swd_controller_cnt == 7'd0 || + (swd_controller_state == 4'd6 || swd_controller_state == 4'd5) && + swd_controller_prescaler_ctr$Q_OUT == 8'd1 && + swd_controller_cnt == 7'd0 || + swd_controller_state == 4'd0 && + (swd_controller_request_in$whas || + swd_controller_reset_in$whas) ; + + // register swd_controller_status + assign swd_controller_status$D_IN = + MUX_swd_controller_status$write_1__SEL_1 ? + MUX_swd_controller_status$write_1__VAL_1 : + 3'd2 ; + assign swd_controller_status$EN = + swd_controller_state == 4'd7 && + swd_controller_prescaler_ctr$Q_OUT == 8'd0 || + WILL_FIRE_RL_do_rw ; + + // register swd_controller_swclk + assign swd_controller_swclk$D_IN = + !MUX_swd_controller_swclk$write_1__SEL_1 || + swd_controller_prescaler_ctr$Q_OUT != 8'd0 ; + assign swd_controller_swclk$EN = + swd_controller_state != 4'd0 && + (swd_controller_prescaler_ctr$Q_OUT == 8'd0 || + swd_controller_prescaler_ctr$Q_OUT == 8'd50) || + swd_controller_state == 4'd0 && + !swd_controller_request_in$whas && + !swd_controller_reset_in$whas ; + + // register swd_controller_swd_out + always@(MUX_swd_controller_data$write_1__SEL_2 or + swd_controller_data or + MUX_swd_controller_swd_out$write_1__SEL_2 or + MUX_swd_controller_swd_out$write_1__VAL_2 or + MUX_swd_controller_swd_out$write_1__SEL_3 or + MUX_swd_controller_swd_out$write_1__VAL_3 or + MUX_swd_controller_swd_out$write_1__SEL_4 or + MUX_swd_controller_swclk$write_1__SEL_2) + begin + case (1'b1) // synopsys parallel_case + MUX_swd_controller_data$write_1__SEL_2: + swd_controller_swd_out$D_IN = swd_controller_data[0]; + MUX_swd_controller_swd_out$write_1__SEL_2: + swd_controller_swd_out$D_IN = + MUX_swd_controller_swd_out$write_1__VAL_2; + MUX_swd_controller_swd_out$write_1__SEL_3: + swd_controller_swd_out$D_IN = + MUX_swd_controller_swd_out$write_1__VAL_3; + MUX_swd_controller_swd_out$write_1__SEL_4: + swd_controller_swd_out$D_IN = 1'd0; + MUX_swd_controller_swclk$write_1__SEL_2: + swd_controller_swd_out$D_IN = 1'd1; + default: swd_controller_swd_out$D_IN = 1'b0 /* unspecified value */ ; + endcase + end + assign swd_controller_swd_out$EN = + swd_controller_state == 4'd6 && + swd_controller_prescaler_ctr$Q_OUT == 8'd0 || + swd_controller_state == 4'd8 && + swd_controller_prescaler_ctr$Q_OUT == 8'd0 || + swd_controller_state == 4'd1 && + swd_controller_prescaler_ctr$Q_OUT == 8'd0 || + (swd_controller_state == 4'd4 || swd_controller_state == 4'd2) && + swd_controller_prescaler_ctr$Q_OUT == 8'd0 || + swd_controller_state == 4'd0 && + !swd_controller_request_in$whas && + !swd_controller_reset_in$whas ; + + // register wdata + assign wdata$D_IN = { wdata[23:0], write_data } ; + assign wdata$EN = + WILL_FIRE_RL_do_bus_write && { en_wdata, en_cmd } == 2'b10 ; + + // submodule swd_controller_prescaler_ctr + assign swd_controller_prescaler_ctr$DATA_A = 8'h0 ; + assign swd_controller_prescaler_ctr$DATA_B = 8'd255 ; + assign swd_controller_prescaler_ctr$DATA_C = 8'h0 ; + assign swd_controller_prescaler_ctr$DATA_F = 8'd99 ; + assign swd_controller_prescaler_ctr$ADDA = 1'b0 ; + assign swd_controller_prescaler_ctr$ADDB = + swd_controller_prescaler_ctr$Q_OUT != 8'd0 ; + assign swd_controller_prescaler_ctr$SETC = 1'b0 ; + assign swd_controller_prescaler_ctr$SETF = + swd_controller_prescaler_ctr$Q_OUT == 8'd0 ; + + // remaining internal signals + assign _0xE79E__q2 = 16'hE79E ; + assign cmd_BITS_1_TO_0__q1 = cmd[1:0] ; + assign i__h1357 = 7'd71 - swd_controller_cnt ; + assign swd_controller_cnt_2_ULE_8___d35 = swd_controller_cnt <= 7'd8 ; + assign swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d307 = + z__h34482 ^ swd_controller_data[32] ; + assign x__h1338 = _0xE79E__q2[i__h1357[3:0]] ; + assign x__h14817 = swd_controller_cnt - 7'd1 ; + assign x__h19311 = x__h19324 ^ cmd_BITS_1_TO_0__q1[1] ; + assign x__h19324 = x__h19326 ^ cmd_BITS_1_TO_0__q1[0] ; + assign x__h19326 = ~cmd[3] ; + assign x__h20464 = x__h20477 ^ cmd_BITS_1_TO_0__q1[1] ; + assign x__h20477 = cmd[3] ^ cmd_BITS_1_TO_0__q1[0] ; + assign z__h23711 = wdata[24] ^ wdata[25] ; + assign z__h23718 = z__h23711 ^ wdata[26] ; + assign z__h23725 = z__h23718 ^ wdata[27] ; + assign z__h23732 = z__h23725 ^ wdata[28] ; + assign z__h23739 = z__h23732 ^ wdata[29] ; + assign z__h23746 = z__h23739 ^ wdata[30] ; + assign z__h23753 = z__h23746 ^ wdata[31] ; + assign z__h23760 = z__h23753 ^ wdata[16] ; + assign z__h23767 = z__h23760 ^ wdata[17] ; + assign z__h23774 = z__h23767 ^ wdata[18] ; + assign z__h23781 = z__h23774 ^ wdata[19] ; + assign z__h23788 = z__h23781 ^ wdata[20] ; + assign z__h23795 = z__h23788 ^ wdata[21] ; + assign z__h23802 = z__h23795 ^ wdata[22] ; + assign z__h23809 = z__h23802 ^ wdata[23] ; + assign z__h23816 = z__h23809 ^ wdata[8] ; + assign z__h23823 = z__h23816 ^ wdata[9] ; + assign z__h23830 = z__h23823 ^ wdata[10] ; + assign z__h23837 = z__h23830 ^ wdata[11] ; + assign z__h23844 = z__h23837 ^ wdata[12] ; + assign z__h23851 = z__h23844 ^ wdata[13] ; + assign z__h23858 = z__h23851 ^ wdata[14] ; + assign z__h23865 = z__h23858 ^ wdata[15] ; + assign z__h23872 = z__h23865 ^ wdata[0] ; + assign z__h23879 = z__h23872 ^ wdata[1] ; + assign z__h23886 = z__h23879 ^ wdata[2] ; + assign z__h23893 = z__h23886 ^ wdata[3] ; + assign z__h23900 = z__h23893 ^ wdata[4] ; + assign z__h23907 = z__h23900 ^ wdata[5] ; + assign z__h23914 = z__h23907 ^ wdata[6] ; + assign z__h34272 = swd_controller_data[0] ^ swd_controller_data[1] ; + assign z__h34279 = z__h34272 ^ swd_controller_data[2] ; + assign z__h34286 = z__h34279 ^ swd_controller_data[3] ; + assign z__h34293 = z__h34286 ^ swd_controller_data[4] ; + assign z__h34300 = z__h34293 ^ swd_controller_data[5] ; + assign z__h34307 = z__h34300 ^ swd_controller_data[6] ; + assign z__h34314 = z__h34307 ^ swd_controller_data[7] ; + assign z__h34321 = z__h34314 ^ swd_controller_data[8] ; + assign z__h34328 = z__h34321 ^ swd_controller_data[9] ; + assign z__h34335 = z__h34328 ^ swd_controller_data[10] ; + assign z__h34342 = z__h34335 ^ swd_controller_data[11] ; + assign z__h34349 = z__h34342 ^ swd_controller_data[12] ; + assign z__h34356 = z__h34349 ^ swd_controller_data[13] ; + assign z__h34363 = z__h34356 ^ swd_controller_data[14] ; + assign z__h34370 = z__h34363 ^ swd_controller_data[15] ; + assign z__h34377 = z__h34370 ^ swd_controller_data[16] ; + assign z__h34384 = z__h34377 ^ swd_controller_data[17] ; + assign z__h34391 = z__h34384 ^ swd_controller_data[18] ; + assign z__h34398 = z__h34391 ^ swd_controller_data[19] ; + assign z__h34405 = z__h34398 ^ swd_controller_data[20] ; + assign z__h34412 = z__h34405 ^ swd_controller_data[21] ; + assign z__h34419 = z__h34412 ^ swd_controller_data[22] ; + assign z__h34426 = z__h34419 ^ swd_controller_data[23] ; + assign z__h34433 = z__h34426 ^ swd_controller_data[24] ; + assign z__h34440 = z__h34433 ^ swd_controller_data[25] ; + assign z__h34447 = z__h34440 ^ swd_controller_data[26] ; + assign z__h34454 = z__h34447 ^ swd_controller_data[27] ; + assign z__h34461 = z__h34454 ^ swd_controller_data[28] ; + assign z__h34468 = z__h34461 ^ swd_controller_data[29] ; + assign z__h34475 = z__h34468 ^ swd_controller_data[30] ; + assign z__h34482 = z__h34475 ^ swd_controller_data[31] ; + + // handling of inlined registers + + always@(posedge CLK) + begin + if (RST_N == `BSV_RESET_VALUE) + begin + bus_reg_rdata <= `BSV_ASSIGNMENT_DELAY 8'd0; + bus_reg_status <= `BSV_ASSIGNMENT_DELAY 8'd0; + cmd <= `BSV_ASSIGNMENT_DELAY 9'd170; + rdata <= `BSV_ASSIGNMENT_DELAY 32'd0; + ready <= `BSV_ASSIGNMENT_DELAY 1'd0; + reg_rdata_cnt <= `BSV_ASSIGNMENT_DELAY 2'd0; + state <= `BSV_ASSIGNMENT_DELAY 2'd0; + status <= `BSV_ASSIGNMENT_DELAY 2'd0; + swd_controller_ack <= `BSV_ASSIGNMENT_DELAY 3'd0; + swd_controller_out_en <= `BSV_ASSIGNMENT_DELAY 1'd1; + swd_controller_state <= `BSV_ASSIGNMENT_DELAY 4'd0; + swd_controller_status <= `BSV_ASSIGNMENT_DELAY 3'd2; + swd_controller_swclk <= `BSV_ASSIGNMENT_DELAY 1'd0; + swd_controller_swd_out <= `BSV_ASSIGNMENT_DELAY 1'd0; + wdata <= `BSV_ASSIGNMENT_DELAY 32'd0; + end + else + begin + if (bus_reg_rdata$EN) + bus_reg_rdata <= `BSV_ASSIGNMENT_DELAY bus_reg_rdata$D_IN; + if (bus_reg_status$EN) + bus_reg_status <= `BSV_ASSIGNMENT_DELAY bus_reg_status$D_IN; + if (cmd$EN) cmd <= `BSV_ASSIGNMENT_DELAY cmd$D_IN; + if (rdata$EN) rdata <= `BSV_ASSIGNMENT_DELAY rdata$D_IN; + if (ready$EN) ready <= `BSV_ASSIGNMENT_DELAY ready$D_IN; + if (reg_rdata_cnt$EN) + reg_rdata_cnt <= `BSV_ASSIGNMENT_DELAY reg_rdata_cnt$D_IN; + if (state$EN) state <= `BSV_ASSIGNMENT_DELAY state$D_IN; + if (status$EN) status <= `BSV_ASSIGNMENT_DELAY status$D_IN; + if (swd_controller_ack$EN) + swd_controller_ack <= `BSV_ASSIGNMENT_DELAY swd_controller_ack$D_IN; + if (swd_controller_out_en$EN) + swd_controller_out_en <= `BSV_ASSIGNMENT_DELAY + swd_controller_out_en$D_IN; + if (swd_controller_state$EN) + swd_controller_state <= `BSV_ASSIGNMENT_DELAY + swd_controller_state$D_IN; + if (swd_controller_status$EN) + swd_controller_status <= `BSV_ASSIGNMENT_DELAY + swd_controller_status$D_IN; + if (swd_controller_swclk$EN) + swd_controller_swclk <= `BSV_ASSIGNMENT_DELAY + swd_controller_swclk$D_IN; + if (swd_controller_swd_out$EN) + swd_controller_swd_out <= `BSV_ASSIGNMENT_DELAY + swd_controller_swd_out$D_IN; + if (wdata$EN) wdata <= `BSV_ASSIGNMENT_DELAY wdata$D_IN; + end + if (swd_controller_cnt$EN) + swd_controller_cnt <= `BSV_ASSIGNMENT_DELAY swd_controller_cnt$D_IN; + if (swd_controller_data$EN) + swd_controller_data <= `BSV_ASSIGNMENT_DELAY swd_controller_data$D_IN; + if (swd_controller_packet$EN) + swd_controller_packet <= `BSV_ASSIGNMENT_DELAY + swd_controller_packet$D_IN; + if (swd_controller_rnw$EN) + swd_controller_rnw <= `BSV_ASSIGNMENT_DELAY swd_controller_rnw$D_IN; + end + + // synopsys translate_off + `ifdef BSV_NO_INITIAL_BLOCKS + `else // not BSV_NO_INITIAL_BLOCKS + initial + begin + bus_reg_rdata = 8'hAA; + bus_reg_status = 8'hAA; + cmd = 9'h0AA; + rdata = 32'hAAAAAAAA; + ready = 1'h0; + reg_rdata_cnt = 2'h2; + state = 2'h2; + status = 2'h2; + swd_controller_ack = 3'h2; + swd_controller_cnt = 7'h2A; + swd_controller_data = 33'h0AAAAAAAA; + swd_controller_out_en = 1'h0; + swd_controller_packet = 8'hAA; + swd_controller_rnw = 1'h0; + swd_controller_state = 4'hA; + swd_controller_status = 3'h2; + swd_controller_swclk = 1'h0; + swd_controller_swd_out = 1'h0; + wdata = 32'hAAAAAAAA; + end + `endif // BSV_NO_INITIAL_BLOCKS + // synopsys translate_on + + // handling of system tasks + + // synopsys translate_off + always@(negedge CLK) + begin + #0; + if (RST_N != `BSV_RESET_VALUE) $write("state: "); + if (RST_N != `BSV_RESET_VALUE) + if (swd_controller_state == 4'd0) $write("IDLE"); + if (RST_N != `BSV_RESET_VALUE) + if (swd_controller_state == 4'd1) $write("PACKET"); + if (RST_N != `BSV_RESET_VALUE) + if (swd_controller_state == 4'd2) $write("P_TRN"); + if (RST_N != `BSV_RESET_VALUE) + if (swd_controller_state == 4'd3) $write("ACK"); + if (RST_N != `BSV_RESET_VALUE) + if (swd_controller_state == 4'd4) $write("A_TRN"); + if (RST_N != `BSV_RESET_VALUE) + if (swd_controller_state == 4'd5) $write("RDATA"); + if (RST_N != `BSV_RESET_VALUE) + if (swd_controller_state == 4'd6) $write("WDATA"); + if (RST_N != `BSV_RESET_VALUE) + if (swd_controller_state == 4'd7) $write("DONE"); + if (RST_N != `BSV_RESET_VALUE) + if (swd_controller_state != 4'd0 && swd_controller_state != 4'd1 && + swd_controller_state != 4'd2 && + swd_controller_state != 4'd3 && + swd_controller_state != 4'd4 && + swd_controller_state != 4'd5 && + swd_controller_state != 4'd6 && + swd_controller_state != 4'd7) + $write("RESET"); + if (RST_N != `BSV_RESET_VALUE) + $write(", swclk: %b, swd_out: %b, swd_in: %b, out_en: %b", + swd_controller_swclk, + swd_controller_swd_out, + swd_in, + swd_controller_out_en, + "\n"); + end + // synopsys translate_on +endmodule // swd_module + diff --git a/fpga-arch/system.vhd b/fpga-arch/system.vhd index 4047acb..f387cc6 100644 --- a/fpga-arch/system.vhd +++ b/fpga-arch/system.vhd @@ -109,6 +109,30 @@ architecture behavior of system is -- | | | | | | | | | | -- +----+ +------+ +----------+ +------+ +-----+ + -- Declaration of Verilog module as a component + COMPONENT swd_module + PORT + ( + CLK : IN STD_LOGIC; + RST_N : IN STD_LOGIC; + address : IN STD_LOGIC_VECTOR(15 DOWNTO 0); + write_data : IN STD_LOGIC_VECTOR(7 DOWNTO 0); + write : IN STD_LOGIC; + read : IN STD_LOGIC; + en_rdata : IN STD_LOGIC; + en_wdata : IN STD_LOGIC; + en_cmd : IN STD_LOGIC; + en_status : IN STD_LOGIC; + reg_rdata : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); + reg_status : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); + swclk : OUT STD_LOGIC; + swd_in : IN STD_LOGIC; + swd_out : OUT STD_LOGIC; + out_en : OUT STD_LOGIC + ); + END COMPONENT; + + -- Function for easier address decoding. function addr_en ( bus_in: bus_in_t; @@ -161,7 +185,8 @@ architecture behavior of system is + 2 -- I2C + 1 -- SPI + 2 -- SPI slave - + 1; -- Clock + + 1 -- Clock + + 1; -- SWD signal mtxl_out: std_logic_vector(mtxl_out_count-1 downto 0); signal mtxl_out_uart_rx: std_logic_vector(uart_count-1 downto 0); signal mtxl_out_pulse_gen_start: std_logic_vector(pulse_gen_count-1 downto 0); @@ -172,6 +197,7 @@ architecture behavior of system is signal mtxl_out_spi_slave_sck: std_logic; signal mtxl_out_spi_slave_ss: std_logic; signal mtxl_out_clock_glitch_start: std_logic; + signal mtxl_out_swd_swdio: std_logic; signal mtxl_out_chain_events: std_logic_vector_array_t(chain_count-1 downto 0)(chain_size-1 downto 0); @@ -184,7 +210,8 @@ architecture behavior of system is + 3 -- I2C module + 4 -- SPI module + 1 -- SPI slave module - + 1; -- Clock + + 1 -- Clock + + 2; -- SWD signal mtxr_in: tristate_array_t(mtxr_in_count-1 downto 0); signal mtxr_in_uart_tx: std_logic_vector(uart_count-1 downto 0); signal mtxr_in_uart_trigger: std_logic_vector(uart_count-1 downto 0); @@ -203,6 +230,9 @@ architecture behavior of system is signal mtxr_in_spi_trigger: std_logic; signal mtxr_in_spi_slave_miso: std_logic; signal mtxr_in_clock_out: std_logic; + signal mtxr_in_swd_swdio: std_logic; + signal mtxr_in_swd_swdio_en: std_logic; + signal mtxr_in_swd_swclk: std_logic; signal mtxr_in_chain_out: std_logic_vector(chain_count-1 downto 0); -- Output signals of the output matrix @@ -258,6 +288,10 @@ architecture behavior of system is constant addr_clock_divisor_a: address_t := x"0a01"; constant addr_clock_divisor_b: address_t := x"0a02"; constant addr_clock_count: address_t := x"0a03"; + constant addr_swd_rdata: address_t := x"0b00"; + constant addr_swd_wdata: address_t := x"0b04"; + constant addr_swd_status: address_t := x"0b10"; + constant addr_swd_cmd: address_t := x"0b20"; constant addr_io_value_base: address_t := x"e000"; constant addr_io_config_base: address_t := x"e001"; constant addr_mtxl_base: address_t := x"f000"; @@ -307,6 +341,10 @@ architecture behavior of system is signal en_clock_divisor_a: std_logic; signal en_clock_divisor_b: std_logic; signal en_clock_count: std_logic; + signal en_swd_rdata: std_logic; + signal en_swd_wdata: std_logic; + signal en_swd_cmd: std_logic; + signal en_swd_status: std_logic; signal en_io_value: std_logic_vector(io_count-1 downto 0); signal en_io_config: std_logic_vector(io_count-1 downto 0); signal en_mtxl_sel: std_logic_vector(mtxl_out_count-1 downto 0); @@ -323,7 +361,8 @@ architecture behavior of system is + 1 -- Power control + 2 -- ISO7816 status and data + 4 -- I2C - + 2; -- SPI + + 2 -- SPI + + 2; -- SWD signal reg_io_value: std_logic_vector_array_t(io_count-1 downto 0) (7 downto 0); signal reg_version_data: byte_t; @@ -335,6 +374,7 @@ architecture behavior of system is signal reg_power_control: byte_t; signal reg_i2c_status, reg_i2c_data, reg_i2c_size_h, reg_i2c_size_l: byte_t; signal reg_spi_status, reg_spi_data: byte_t; + signal reg_swd_status, reg_swd_rdata: byte_t; -- State of the LEDs (when override is disabled in LEDs module). signal leds: std_logic_vector(23 downto 0); @@ -434,6 +474,10 @@ begin en_clock_divisor_a <= addr_en(bus_in, addr_clock_divisor_a); en_clock_divisor_b <= addr_en(bus_in, addr_clock_divisor_b); en_clock_count <= addr_en(bus_in, addr_clock_count); + en_swd_rdata <= addr_en(bus_in, addr_swd_rdata); + en_swd_wdata <= addr_en(bus_in, addr_swd_wdata); + en_swd_cmd <= addr_en(bus_in, addr_swd_cmd); + en_swd_status <= addr_en(bus_in, addr_swd_status); en_io_value <= addr_en_loop(bus_in, addr_io_value_base, x"0010", io_count); en_io_config <= addr_en_loop(bus_in, addr_io_config_base, x"0010", io_count); @@ -461,7 +505,9 @@ begin reg_iso7816_status & reg_iso7816_data & reg_spi_status & - reg_spi_data, + reg_spi_data & + reg_swd_rdata & + reg_swd_status, enables => en_io_value & en_pulse_gen_status & @@ -476,7 +522,9 @@ begin en_iso7816_status & en_iso7816_data & en_spi_status & - en_spi_data, + en_spi_data & + en_swd_rdata & + en_swd_status, value => bus_out.read_data ); -- I/O modules @@ -694,6 +742,25 @@ begin output => mtxr_in_clock_out, glitch_start => mtxl_out_clock_glitch_start ); + c_swd: component swd_module + port map ( + CLK => clock, + RST_N => reset_n, + address => bus_in.address, + write_data => bus_in.write_data, + write => bus_in.write, + read => bus_in.read, + en_rdata => en_swd_rdata, + en_wdata => en_swd_wdata, + en_cmd => en_swd_cmd, + en_status => en_swd_status, + reg_rdata => reg_swd_rdata, + reg_status => reg_swd_status, + swclk => mtxr_in_swd_swclk, + swd_in => mtxl_out_swd_swdio, + swd_out => mtxr_in_swd_swdio, + out_en => mtxr_in_swd_swdio_en ); + -- Left matrix module e_left_matrix_module: entity work.left_matrix_module generic map ( @@ -733,6 +800,8 @@ begin end loop; mtxl_out_clock_glitch_start <= mtxl_out(i); i := i + 1; + mtxl_out_swd_swdio <= mtxl_out(i); + i := i + 1; assert i = mtxl_out_count; end process; @@ -783,7 +852,11 @@ begin mtxr_in_spi_trigger, mtxr_in_spi_slave_miso, mtxr_in_chain_out, - mtxr_in_clock_out ) + mtxr_in_clock_out, + mtxr_in_swd_swclk, + mtxr_in_swd_swdio, + mtxr_in_swd_swdio_en + ) variable i: integer; begin mtxr_in(0) <= "00"; -- Z @@ -831,6 +904,9 @@ begin -- Clock module mtxr_in(i) <= "1" & mtxr_in_clock_out; i := i + 1; + mtxr_in(i) <= "1" & mtxr_in_swd_swclk; + mtxr_in(i+1) <= mtxr_in_swd_swdio_en & mtxr_in_swd_swdio; + i := i + 2; -- If you add other signals, please dont forget to update the sensivity -- list for simulation support. assert i = mtxr_in_count; From d78596d670814efb0fdb993df54521c2e0d02a67 Mon Sep 17 00:00:00 2001 From: cchr Date: Wed, 17 Jul 2024 17:59:34 +0200 Subject: [PATCH 02/24] Use version 10.0 --- api/scaffold/__init__.py | 18 +++++------------- fpga-arch/system.vhd | 2 +- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/api/scaffold/__init__.py b/api/scaffold/__init__.py index 0f950a5..b10a9f8 100644 --- a/api/scaffold/__init__.py +++ b/api/scaffold/__init__.py @@ -2156,6 +2156,7 @@ def __init__( "0.7.2", "0.8", "0.9", + "0.10", ) ], ) @@ -2260,12 +2261,10 @@ def connect( self.clocks.append(clock) self.__setattr__(f"clock{i}", clock) -# CCHR # Declare the swd module - if self.version >= "0.9": + if self.version >= parse_version("0.10"): self.swd = swd = SWD(self) self.__setattr__("swd", swd) -# CCHR # Create the ISO7816 module self.iso7816 = ISO7816(self) @@ -2324,10 +2323,8 @@ def connect( self.add_mtxl_out(f"/chain{i}/event{j}") for i in range(len(self.clocks)): self.add_mtxl_out(f"/clock{i}/glitch") -# CCHR - if self.version >= "0.9": + if self.version >= parse_version("0.10"): self.add_mtxl_out("/swd/swd_in") -# CCHR # FPGA right matrix input signals # Update this section when adding new modules with outpus @@ -2359,11 +2356,9 @@ def connect( self.add_mtxr_in(f"/chain{i}/trigger") for i in range(len(self.clocks)): self.add_mtxr_in(f"/clock{i}/out") -# CCHR - if self.version >= "0.9": + if self.version >= parse_version("0.10"): self.add_mtxr_in("/swd/swclk") self.add_mtxr_in("/swd/swd_out") -# CCHR # FPGA right matrix output signals self.add_mtxr_out("/io/a0") @@ -2429,8 +2424,5 @@ def reset_config(self, init_ios=False): i2c.reset_config() for spi in self.spis: spi.reset_registers() -# CCHR - if self.version >= "0.9": + if self.version >= parse_version("0.10"): self.swd.reset_registers() -# OHE I commented out #self.swd.reset() -# CCHR diff --git a/fpga-arch/system.vhd b/fpga-arch/system.vhd index f387cc6..4e8cb51 100644 --- a/fpga-arch/system.vhd +++ b/fpga-arch/system.vhd @@ -568,7 +568,7 @@ begin -- Version module e_version_module: entity work.version_module - generic map (version => "scaffold-0.9") + generic map (version => "scaffold-0.10") port map ( clock => clock, reset_n => reset_n, From 7aceffac03bd5ae50d7ace5bbd5725ebdfea05b8 Mon Sep 17 00:00:00 2001 From: cchr Date: Mon, 22 Jul 2024 10:29:30 +0200 Subject: [PATCH 03/24] Add licensing information --- fpga-arch/{ => bsv}/Counter.v | 37 ++- fpga-arch/bsv/Prescaler.bsv | 56 +++++ fpga-arch/bsv/SWD.bsv | 188 ++++++++++++++ fpga-arch/bsv/SWDInner.bsv | 452 ++++++++++++++++++++++++++++++++++ 4 files changed, 732 insertions(+), 1 deletion(-) rename fpga-arch/{ => bsv}/Counter.v (50%) create mode 100644 fpga-arch/bsv/Prescaler.bsv create mode 100644 fpga-arch/bsv/SWD.bsv create mode 100644 fpga-arch/bsv/SWDInner.bsv diff --git a/fpga-arch/Counter.v b/fpga-arch/bsv/Counter.v similarity index 50% rename from fpga-arch/Counter.v rename to fpga-arch/bsv/Counter.v index fc51e0c..87ddb51 100644 --- a/fpga-arch/Counter.v +++ b/fpga-arch/bsv/Counter.v @@ -1,4 +1,39 @@ - +// +// Copied without modifications from: +// https://github.com/B-Lang-org/bsc/blob/9a97f9d037c462e42441b6af8d0000314302214f/src/Verilog/Counter.v +// +// Copyright (c) 2020 Bluespec, Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// 3. Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + +# `ifdef BSV_ASSIGNMENT_DELAY `else `define BSV_ASSIGNMENT_DELAY diff --git a/fpga-arch/bsv/Prescaler.bsv b/fpga-arch/bsv/Prescaler.bsv new file mode 100644 index 0000000..0fca07b --- /dev/null +++ b/fpga-arch/bsv/Prescaler.bsv @@ -0,0 +1,56 @@ +// This file is part of Scaffold +// +// Scaffold is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// +// +// Copyright 2024 Ledger SAS, written by Charles Christen + +package Prescaler; + +import Counter::*; + +(* always_ready, always_enabled *) +interface Prescaler#(numeric type n); + method Bool rising; + method Bool falling; + method Bool pre_rising; +endinterface + +module mkPrescaler (Prescaler#(prescale)) + provisos ( + Mul#(__a, 2, prescale), + Add#(ctr_max, 1, prescale), + Log#(ctr_max, __b), + Add#(__b, 1, ctr_sz) + ); + + Counter#(ctr_sz) ctr <- mkCounter(fromInteger(valueof(ctr_max))); + + (* fire_when_enabled, no_implicit_conditions *) + rule count_dow(ctr.value > 0); + ctr.down(); + endrule + + (* fire_when_enabled, no_implicit_conditions *) + rule reset_count(ctr.value == 0); + ctr.setF(fromInteger(valueof(ctr_max))); + endrule + + method rising = (ctr.value == 0); + method pre_rising = (ctr.value == 1); + method falling = (ctr.value == fromInteger(valueof(__a))); + +endmodule + +endpackage diff --git a/fpga-arch/bsv/SWD.bsv b/fpga-arch/bsv/SWD.bsv new file mode 100644 index 0000000..01f6df1 --- /dev/null +++ b/fpga-arch/bsv/SWD.bsv @@ -0,0 +1,188 @@ +// This file is part of Scaffold +// +// Scaffold is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// +// +// Copyright 2024 Ledger SAS, written by Charles Christen + +import SWDInner::*; + +import GetPut::*; +import Vector::*; +import StmtFSM::*; +import ClientServer::*; + +(* always_ready, always_enabled *) +interface ScaffoldBus; + // bus_in_t + (* prefix="" *) method Action address((* port="address" *) Bit#(16) a); + (* prefix="" *) method Action write_data((* port="write_data" *) Bit#(8) w); + (* prefix="" *) method Action write((* port="write" *) Bit#(1) b); + (* prefix="" *) method Action read((* port="read" *) Bit#(1) b); + + // register selection + (* prefix="" *) method Action en_rdata((* port="en_rdata" *) Bit#(1) en); + (* prefix="" *) method Action en_wdata((* port="en_wdata" *) Bit#(1) en); + (* prefix="" *) method Action en_cmd((* port="en_cmd" *) Bit#(1) en); + (* prefix="" *) method Action en_status((* port="en_status" *) Bit#(1) en); + + // readable register out + (* prefix="" *) method Bit#(8) reg_rdata; + (* prefix="" *) method Bit#(8) reg_status; +endinterface + +interface ScaffoldSWDModule; + (* prefix="" *) interface ScaffoldBus bus; + (* prefix="" *) interface SWDControllerPins pins; +endinterface + +typedef struct { + Bit#(1) reset; + Bit#(3) reserved; + Bit#(1) apndp; + Bit#(1) rnw; + Bit#(2) addr; +} Cmd deriving (Eq, Bits); + +typedef enum { + IDLE, + RESET, + RW +} State deriving (Eq, Bits); + +(* synthesize *) +module swd_module (ScaffoldSWDModule); + SWDController#(100) swd_controller <- mkSWDController(); + + Wire#(Bit#(16)) bus_address <- mkDWire(0); + Wire#(Bit#(8)) bus_write_data <- mkDWire(0); + Wire#(Bit#(1)) bus_write <- mkDWire(0); + Wire#(Bit#(1)) bus_read <- mkDWire(0); + Wire#(Bit#(1)) bus_en_rdata <- mkDWire(0); + Wire#(Bit#(1)) bus_en_wdata <- mkDWire(0); + Wire#(Bit#(1)) bus_en_cmd <- mkDWire(0); + Wire#(Bit#(1)) bus_en_status <- mkDWire(0); + + Reg#(Bit#(8)) bus_reg_rdata <- mkReg(0); + Reg#(Bit#(8)) bus_reg_status <- mkReg(0); + + Reg#(Bit#(2)) reg_rdata_cnt <- mkReg(0); + + Reg#(Vector#(4, Bit#(8))) rdata <- mkReg(unpack(0)); + Reg#(Status) status <- mkReg(unpack(0)); + Reg#(Vector#(4, Bit#(8))) wdata <- mkReg(unpack(0)); + Reg#(Maybe#(Cmd)) cmd <- mkReg(tagged Invalid); + + Reg#(Bool) ready <- mkReg(False); + Reg#(State) state <- mkReg(IDLE); + + rule do_bus_read (bus_read == 1); + case ({bus_en_rdata, bus_en_status}) matches + 2'b10: + begin + bus_reg_rdata <= rdata[reg_rdata_cnt]; + reg_rdata_cnt <= reg_rdata_cnt + 1; + end + 2'b01: bus_reg_status <= {pack(state == IDLE), 5'b0, pack(status)}; + endcase + endrule + + rule do_bus_write ((bus_write == 1) && (state == IDLE)); + case ({bus_en_wdata, bus_en_cmd}) matches + 2'b10: wdata <= shiftInAt0(wdata, bus_write_data); + 2'b01: cmd <= tagged Valid(unpack(bus_write_data)); + endcase + endrule + + rule do_ready; + ready <= swd_controller.ready; + endrule + + // ONLY do something if there is a valid command registered, and if + // the user is not currently writing to some register. + rule do_idle ((state == IDLE) && (bus_write == 0) && isValid(cmd)); + let new_cmd = fromMaybe(?, cmd); + + if (new_cmd.reset == 1) begin + swd_controller.reset(); + state <= RESET; + end + + else if (new_cmd.rnw == 1) begin + swd_controller.rw.request.put( + tagged Read { register: Register { apndp: new_cmd.apndp, addr: new_cmd.addr } } + ); + state <= RW; + end + + else begin + swd_controller.rw.request.put( + tagged Write { register: Register { apndp: new_cmd.apndp, addr: new_cmd.addr }, wdata: pack(reverse(wdata)) } + ); + state <= RW; + end + endrule + + rule do_reset (state == RESET); + if (ready) begin + swd_controller.rw.request.put( + tagged Read { register: Register { apndp: 0, addr: 0 } } + ); + state <= RW; + end + endrule + + rule do_rw (state == RW); + let response <- swd_controller.rw.response.get(); + case (response) matches + tagged Write .w_resp: begin + status <= w_resp.status; + rdata <= unpack(0); + end + tagged Read .r_resp: begin + Vector#(32, Bit#(1)) resp_rdata; + resp_rdata = take(unpack(r_resp.rdata)); + + if (parity(r_resp.rdata) != 0) begin + status <= ERROR; + rdata <= unpack(0); + end + else begin + status <= r_resp.status; + rdata <= unpack(pack(resp_rdata)); + end + end + endcase + + cmd <= tagged Invalid; + state <= IDLE; + endrule + + interface ScaffoldBus bus; + method Action address(a) = bus_address._write(a); + method Action write_data(w) = bus_write_data._write(w); + method Action write(b) = bus_write._write(b); + method Action read(b) = bus_read._write(b); + + method Action en_rdata(en) = bus_en_rdata._write(en); + method Action en_wdata(en) = bus_en_wdata._write(en); + method Action en_cmd(en) = bus_en_cmd._write(en); + method Action en_status(en) = bus_en_status._write(en); + + method Bit#(8) reg_rdata = bus_reg_rdata; + method Bit#(8) reg_status = bus_reg_status; + endinterface + + interface SWDControllerPins pins = swd_controller.pins; +endmodule \ No newline at end of file diff --git a/fpga-arch/bsv/SWDInner.bsv b/fpga-arch/bsv/SWDInner.bsv new file mode 100644 index 0000000..e23df00 --- /dev/null +++ b/fpga-arch/bsv/SWDInner.bsv @@ -0,0 +1,452 @@ +// This file is part of Scaffold +// +// Scaffold is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . +// +// +// Copyright 2024 Ledger SAS, written by Charles Christen + +package SWDInner; + +import Prescaler::*; + +import StmtFSM::*; +import GetPut::*; +import Vector::*; +import ClientServer::*; + +/// An AP or DP register. +typedef struct { + Bit#(1) apndp; + Bit#(2) addr; +} Register deriving (Eq, Bits); + +/// A full 8-bits request packet. +typedef struct { + Bit#(1) start; + Bit#(1) apndp; + Bit#(1) rnw; + Bit#(2) addr; + Bit#(1) parity; + Bit#(1) stop; + Bit#(1) park; +} RequestPacket deriving (Eq, Bits); + +/// A transaction status. +typedef enum { + OK, + WAIT, + FAULT, + ERROR +} Status deriving (Eq, Bits, FShow); + +/// The internal state of the SWD controller. +typedef enum { + IDLE, + PACKET, + P_TRN, + ACK, + A_TRN, + RDATA, + WDATA, + DONE, + RESET +} State deriving (Eq, Bits, FShow); + +/// A request, for either a Read or a Write +/// transaction. +typedef union tagged { + struct { + Register register; + Bit#(32) wdata; + } Write; + + struct { + Register register; + } Read; +} Request deriving (Eq, Bits); + +/// A response, to either a Read or a Write +/// transaction. +typedef union tagged { + struct { + Status status; + } Write; + + struct { + Status status; + Bit#(33) rdata; + } Read; +} Response deriving (Eq, Bits); + +/// The peripheral-facing pins of the SWD controller, +/// with swdio split into swd_in and swd_out. +(* always_ready, always_enabled *) +interface SWDControllerPins; + (* prefix="" *) method Bit#(1) swclk; + (* prefix="" *) method Action swd_in((* port="swd_in" *) Bit#(1) b); + (* prefix="" *) method Bit#(1) swd_out; + (* prefix="" *) method Bool out_en; +endinterface + +/// The full SWD controller interface, with endpoints for +/// issuing Read and Write requests, and peripheral-facing +/// pins. +interface SWDController#(numeric type clk_divider); + method Action reset; + interface Server#(Request, Response) rw; + (* always_ready, always_enabled *) method Bool ready; + (* always_ready, always_enabled *) interface SWDControllerPins pins; +endinterface + +module mkSWDController (SWDController#(clk_divider)) + provisos ( + Mul#(__a, 2, clk_divider), + Add#(__b, 1, clk_divider) + ); + + // When a request comes in, the packet (and data, in case of a write request) + // are registered, and swclk is kicked-off. + // We then move sequencially through the steps of the transaction, shifting out + // or in bits at a time, synchronously with the generated swclk rising/falling edges. + // When the transaction is done, the transaction status is updated and marked + // as Valid, triggering the release of the Get interface of the R/W server. + // + // The tricky thing, however, is to coordinate the state changes with the rising + // and falling edges of the SWD clock. + // Indeed we want to say that on the rising edge of swclk, meaning when it is zero + // but will be one in the next cycle, we want to do a certain operation, that depends + // on which step of the transaction we are in, i.e. which state. + // Thus the state must have been updated *before*, on the cycle immediately preceding + // the cycle itself preceding swclk == 1. + // This is what [prescaler.pre_rising] is for. + + Prescaler#(clk_divider) prescaler <- mkPrescaler(); + + // Status and ACK of the current transaction. + Reg#(Maybe#(Status)) status <- mkReg(tagged Invalid); + Reg#(Vector#(3, Bit#(1))) ack <- mkReg(unpack(0)); + + // Controller pins. + Reg#(Bit#(1)) swd_out <- mkReg(0); + Wire#(Bit#(1)) swd_in <- mkDWire(0); + Reg#(Bool) out_en <- mkReg(True); + Reg#(Bit#(1)) swclk <- mkReg(0); + + // Inner state. + Reg#(State) state <- mkReg(IDLE); + Reg#(Bool) rnw <- mkRegU; + Reg#(Vector#(8, Bit#(1))) packet <- mkRegU; + Reg#(Vector#(33, Bit#(1))) data <- mkRegU; + + // Counter for tracking bits in the transfered packet/data. + Reg#(Bit#(7)) cnt <- mkRegU; + + // Same-cycle signals + PulseWire request_in <- mkPulseWire(); + PulseWire reset_in <- mkPulseWire(); + + // Generate the SWD clock, whenever there is an + // ongoing transaction. + rule do_swclk (state != IDLE); + if (prescaler.rising) begin + swclk <= 0; + end + else if (prescaler.falling) begin + swclk <= 1; + end + endrule + + // SWDIO is treated as an input only when in + // the ACK or RDATA phase. + rule do_out_en; + if ((state == RESET) || (state == PACKET) || (state == WDATA)) begin + out_en <= True; + end + else begin + out_en <= False; + end + endrule + + // Stop idling when a request has been received. + rule do_idle (state == IDLE); + if (request_in) begin + state <= PACKET; + cnt <= 10; + end + else if (reset_in) begin + state <= RESET; + cnt <= 126; + end + else begin + swclk <= 1; + swd_out <= 1; + end + endrule + + // Shift out the reset and switch sequence + rule do_reset (state == RESET); + if (prescaler.rising) begin + // > 50 cycles with swdio high (the specification says + // "more than 50", we err on the side on caution and + // take it to mean strictly more) + if (cnt > 71) begin + swd_out <= 1; + cnt <= cnt - 1; + end + // followed by the 16 bits of the JTAG-to-SWD switching + // sequence + else if (cnt > 55) begin + let switch_sequence = 16'hE79E; + swd_out <= switch_sequence[71 - cnt]; + cnt <= cnt - 1; + end + // and finally > 50 more cycles high + // (bits xx to 1, because the case cnt == 0 is preempted + // by the pre_rising condition below) + else begin + swd_out <= 1; + cnt <= cnt - 1; + end + end + + else if (prescaler.pre_rising && (cnt == 0)) begin + state <= IDLE; + end + endrule + + // Shift out the command packet. + rule do_packet (state == PACKET); + if (prescaler.rising) begin + if (cnt > 8) begin + swd_out <= 0; + cnt <= cnt - 1; + end + + else begin + // On every rising edge of the generated swclk, we need to shift out a + // new bit of the packet + swd_out <= last(packet); + packet <= shiftInAt0(packet, 0); + cnt <= cnt - 1; + end + end + + // If we have shifted out the last bit of the packet, + // and the next swclk rising edge is upcoming shortly, + // we need to pre-emptively transition to the next state (the TRN period) + // so that the corresponding rule is enabled when prescaler.rising becomes true, + // so that it can actually do something useful on the very same cycle + // where swclk is going to be high. + else if (prescaler.pre_rising && (cnt == 0)) begin + state <= P_TRN; + end + + endrule + + // Shift out a TRN bit immediately following the packet. + rule do_p_trn (state == P_TRN); + if (prescaler.rising) begin + swd_out <= 0; + end + + else if (prescaler.pre_rising) begin + cnt <= 3; + state <= ACK; + end + endrule + + // Shift in the received ACK, by sampling the swd_in line in the + // middle of the swclk cycles. + rule do_ack (state == ACK); + if (prescaler.rising) begin + cnt <= cnt - 1; + ack <= shiftInAt0(ack, swd_in); + end + + else begin + // if (prescaler.falling) begin + // ack <= shiftInAt0(ack, swd_in); + // end + + if (prescaler.pre_rising && (cnt == 0)) begin + // If we're shifting in the last ACK bit, next up will either + // be a TRN period or the RDATA, depending on wether the current + // request is a Read or a Write. + if (rnw) begin + cnt <= 33; + state <= RDATA; + end + else begin + state <= A_TRN; + end + end + end + endrule + + // Shift out a TRN bit immediately following the ACK. + // If the ACK is OK, go through with the DATA phase, + // otherwise abort. + rule do_a_trn (state == A_TRN); + if (prescaler.rising) begin + swd_out <= 0; + end + + else if (prescaler.pre_rising) begin + case (pack(ack)) matches + 3'b100: + begin + cnt <= 33; + state <= WDATA; + end + default: + begin + cnt <= 1; + state <= DONE; + end + endcase + end + endrule + + // Shift in the 32-bits read data, plus parity bit. + rule do_rdata (state == RDATA); + if (prescaler.rising) begin + cnt <= cnt - 1; + data <= shiftInAtN(data, swd_in); + end + + else begin + // if (prescaler.falling) begin + // data <= shiftInAtN(data, swd_in); + // end + + if (prescaler.pre_rising && (cnt == 0)) begin + cnt <= 1; + state <= DONE; + end + end + endrule + + // Shift out the 32-bits write data, and parity bit. + rule do_wdata (state == WDATA); + if (prescaler.rising) begin + swd_out <= data[0]; + data <= shiftInAtN(data, 0); + cnt <= cnt - 1; + end + + else if (prescaler.pre_rising && (cnt == 0)) begin + cnt <= 1; + state <= DONE; + end + endrule + + // We're done. Update the status but keep swclk going for + // a full period, and then go back to IDLE. + rule do_done (state == DONE); + if (prescaler.rising) begin + cnt <= cnt - 1; + + case (pack(ack)) matches + 3'b100: status <= Valid(OK); + 3'b010: status <= Valid(WAIT); + 3'b001: status <= Valid(FAULT); + default: status <= Valid(ERROR); + endcase + end + + else if (prescaler.pre_rising && (cnt == 0)) begin + state <= IDLE; + end + endrule + + // For debug purposes. + rule log; + $display($format("state: ") + fshow(state), ", swclk: %b, swd_out: %b, swd_in: %b, out_en: %b", + swclk, swd_out, swd_in, out_en); + endrule + + // Interface methods and subinterfaces + // + method Bool ready = (state == IDLE); + method Action reset if (state == IDLE); + reset_in.send(); + endmethod + + interface Server rw; + interface Put request; + method Action put(req) if ((state == IDLE) && !isValid(status)); + case (req) matches + tagged Write .w_in : begin + let apndp = w_in.register.apndp; + let addr = w_in.register.addr; + let p = apndp ^ 0 ^ addr[0] ^ addr[1]; + packet <= unpack(pack(RequestPacket { + start: 1, + apndp: apndp, + rnw: 0, + addr: addr, + parity: p, + stop: 0, + park: 1 })); + data <= append(unpack(w_in.wdata), replicate(parity(w_in.wdata))); + rnw <= False; + request_in.send(); + end + tagged Read .r_in : begin + let apndp = r_in.register.apndp; + let addr = r_in.register.addr; + let p = apndp ^ 1 ^ addr[0] ^ addr[1]; + packet <= unpack(pack(RequestPacket { + start: 1, + apndp: apndp, + rnw: 1, + addr: addr, + parity: p, + stop: 0, + park: 1 })); + rnw <= True; + request_in.send(); + end + endcase + endmethod + endinterface + + interface Get response; + method ActionValue#(Response) get() if ((state == IDLE) && isValid(status)); + let transaction_status = fromMaybe(?, status); + Response ret; + ret = rnw ? tagged Read { status: transaction_status, rdata: pack(data) } : + tagged Write { status: transaction_status }; + + // reset state + status <= tagged Invalid; + data <= unpack(0); + packet <= unpack(0); + + return ret; + endmethod + endinterface + endinterface + + interface SWDControllerPins pins; + method swclk = swclk; + method swd_out = swd_out; + method Action swd_in(b); + swd_in <= b; + endmethod + method out_en = out_en; + endinterface +endmodule + +endpackage \ No newline at end of file From bb9e5042bd25a324f94f0c3ca77b4905ebbb3bc5 Mon Sep 17 00:00:00 2001 From: cchr Date: Mon, 22 Jul 2024 10:35:45 +0200 Subject: [PATCH 04/24] Remove useless comments --- api/scaffold/__init__.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/api/scaffold/__init__.py b/api/scaffold/__init__.py index b10a9f8..d1e9fc9 100644 --- a/api/scaffold/__init__.py +++ b/api/scaffold/__init__.py @@ -1605,7 +1605,6 @@ def glitch_count(self, value): self.reg_count.set(value) -# CCHR class SWDStatus(Enum): OK = 0 WAIT = 1 @@ -1660,7 +1659,6 @@ def rdata(self): int.from_bytes(self.reg_rdata.read(), 'little') << 8 | \ int.from_bytes(self.reg_rdata.read(), 'little') << 16 | \ int.from_bytes(self.reg_rdata.read(), 'little') << 24 -# CCHR class IOMode(Enum): From 68065a1d068f97ce98fae1c5897fcc05082e0a2c Mon Sep 17 00:00:00 2001 From: cchr Date: Mon, 29 Jul 2024 18:43:39 +0200 Subject: [PATCH 05/24] Add API call for debug power up --- api/scaffold/__init__.py | 14 ++++++++++++++ fpga-arch/swd_module.v | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/api/scaffold/__init__.py b/api/scaffold/__init__.py index d1e9fc9..c08f8e3 100644 --- a/api/scaffold/__init__.py +++ b/api/scaffold/__init__.py @@ -1635,6 +1635,7 @@ def __init__(self, parent): def reset(self): self.reg_cmd.write(0x80) + self.read(0, 0) return self.status() def read(self, apndp, addr): @@ -1651,6 +1652,19 @@ def write(self, apndp, addr, wdata): self.reg_cmd.write(val) return self.status() + def clear_errors(self): + self.write(0, 0, 0b11110) + + def debug_power_up(self, retry=100): + self.clear_errors() + self.write(0, 0x4, (1 << 28) | (1 << 30)) + for _ in range(retry): + (status, ctrl_stat) = self.read(0, 0x4) + print("{:032b}".format(ctrl_stat)) + if ((ctrl_stat >> 29) & 0x1) == 1 and ((ctrl_stat >> 31) & 0x1) == 1: + return True + return False + def status(self): return SWDStatus(int.from_bytes(self.reg_status.read(), 'little') & 0b11) diff --git a/fpga-arch/swd_module.v b/fpga-arch/swd_module.v index edc592e..5daa068 100644 --- a/fpga-arch/swd_module.v +++ b/fpga-arch/swd_module.v @@ -1,7 +1,7 @@ // // Generated by Bluespec Compiler, version 2024.01-9-gc481d7f5 (build c481d7f5) // -// On Wed Jul 17 16:12:33 CEST 2024 +// On Mon Jul 29 18:28:06 CEST 2024 // // // Ports: From 01806ed3551993491859584abc2d6eaea6fffa72 Mon Sep 17 00:00:00 2001 From: cchr Date: Tue, 30 Jul 2024 11:10:37 +0200 Subject: [PATCH 06/24] Better comments --- api/scaffold/__init__.py | 41 ++++++++++++++++++++++++++++++++------ fpga-arch/bsv/SWDInner.bsv | 13 ++++++------ 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/api/scaffold/__init__.py b/api/scaffold/__init__.py index c08f8e3..304481f 100644 --- a/api/scaffold/__init__.py +++ b/api/scaffold/__init__.py @@ -1634,16 +1634,34 @@ def __init__(self, parent): self.add_register("cmd", "w", base + 0x20) def reset(self): + """ + Reset the debug interface. This emits a reset sequence, followed by + the JTAG-to-SWD select sequence and a second reset sequence. The deviceid + register is then read. + """ self.reg_cmd.write(0x80) self.read(0, 0) return self.status() def read(self, apndp, addr): + """ + Emits a read command to a given debug register. + + :param apndp: Address space of the register (0 for DP, 1 for AP). + :param addr: Address of the register. + """ val = 0b0000_0100 | ((apndp & 0b1) << 3) | (addr & 0b11) self.reg_cmd.write(val) return (self.status(), self.rdata()) - def write(self, apndp, addr, wdata): + def write(self, apndp, addr, wdata: int): + """ + Emits a write command to a given debug register. + + :param apndp: Address space of the register (0 for DP, 1 for AP). + :param addr: Address of the register. + :param wdata: 32-bit integer to write into the register. + """ val = 0b0000_0000 | ((apndp & 0b1) << 3) | (addr & 0b11) self.reg_wdata.write(wdata & 0xff) self.reg_wdata.write((wdata >> 8) & 0xff) @@ -1653,26 +1671,37 @@ def write(self, apndp, addr, wdata): return self.status() def clear_errors(self): + """ + Clear any previous errors. + """ self.write(0, 0, 0b11110) - def debug_power_up(self, retry=100): + def debug_power_up(self, retry=10): + """ + Fully powers up the debug interface by writing to the CRTL/STAT register. + """ self.clear_errors() self.write(0, 0x4, (1 << 28) | (1 << 30)) for _ in range(retry): (status, ctrl_stat) = self.read(0, 0x4) - print("{:032b}".format(ctrl_stat)) if ((ctrl_stat >> 29) & 0x1) == 1 and ((ctrl_stat >> 31) & 0x1) == 1: return True return False def status(self): + """ + Retrieve the status of the last emitted SWD transaction. + """ return SWDStatus(int.from_bytes(self.reg_status.read(), 'little') & 0b11) def rdata(self): + """ + Retrieve the data read by the last emitted Read transaction. + """ return int.from_bytes(self.reg_rdata.read(), 'little') | \ - int.from_bytes(self.reg_rdata.read(), 'little') << 8 | \ - int.from_bytes(self.reg_rdata.read(), 'little') << 16 | \ - int.from_bytes(self.reg_rdata.read(), 'little') << 24 + int.from_bytes(self.reg_rdata.read(), 'little') << 8 | \ + int.from_bytes(self.reg_rdata.read(), 'little') << 16 | \ + int.from_bytes(self.reg_rdata.read(), 'little') << 24 class IOMode(Enum): diff --git a/fpga-arch/bsv/SWDInner.bsv b/fpga-arch/bsv/SWDInner.bsv index e23df00..deae54b 100644 --- a/fpga-arch/bsv/SWDInner.bsv +++ b/fpga-arch/bsv/SWDInner.bsv @@ -118,17 +118,17 @@ module mkSWDController (SWDController#(clk_divider)) // When a request comes in, the packet (and data, in case of a write request) // are registered, and swclk is kicked-off. // We then move sequencially through the steps of the transaction, shifting out - // or in bits at a time, synchronously with the generated swclk rising/falling edges. + // or in bits at a time, synchronously with the generated swclk falling/rising edges. // When the transaction is done, the transaction status is updated and marked // as Valid, triggering the release of the Get interface of the R/W server. // // The tricky thing, however, is to coordinate the state changes with the rising // and falling edges of the SWD clock. - // Indeed we want to say that on the rising edge of swclk, meaning when it is zero + // Indeed we want to say that on the rising edge of the prescaler, meaning when it is zero // but will be one in the next cycle, we want to do a certain operation, that depends // on which step of the transaction we are in, i.e. which state. // Thus the state must have been updated *before*, on the cycle immediately preceding - // the cycle itself preceding swclk == 1. + // the cycle itself preceding swclk == 0. // This is what [prescaler.pre_rising] is for. Prescaler#(clk_divider) prescaler <- mkPrescaler(); @@ -158,6 +158,7 @@ module mkSWDController (SWDController#(clk_divider)) // Generate the SWD clock, whenever there is an // ongoing transaction. + // Note that the polarity is inverted (the peripheral samples the IO line on rising edges of swclk) rule do_swclk (state != IDLE); if (prescaler.rising) begin swclk <= 0; @@ -234,7 +235,7 @@ module mkSWDController (SWDController#(clk_divider)) end else begin - // On every rising edge of the generated swclk, we need to shift out a + // On every falling edge of the generated swclk, we need to shift out a // new bit of the packet swd_out <= last(packet); packet <= shiftInAt0(packet, 0); @@ -243,11 +244,11 @@ module mkSWDController (SWDController#(clk_divider)) end // If we have shifted out the last bit of the packet, - // and the next swclk rising edge is upcoming shortly, + // and the next swclk falling edge is upcoming shortly, // we need to pre-emptively transition to the next state (the TRN period) // so that the corresponding rule is enabled when prescaler.rising becomes true, // so that it can actually do something useful on the very same cycle - // where swclk is going to be high. + // where swclk is going to be low. else if (prescaler.pre_rising && (cnt == 0)) begin state <= P_TRN; end From d459f3e07eb3582a56a4e383c90070678868941d Mon Sep 17 00:00:00 2001 From: cchr Date: Thu, 1 Aug 2024 20:11:27 +0200 Subject: [PATCH 07/24] Fix API bugs --- api/scaffold/__init__.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/api/scaffold/__init__.py b/api/scaffold/__init__.py index 304481f..5625789 100644 --- a/api/scaffold/__init__.py +++ b/api/scaffold/__init__.py @@ -1650,7 +1650,8 @@ def read(self, apndp, addr): :param apndp: Address space of the register (0 for DP, 1 for AP). :param addr: Address of the register. """ - val = 0b0000_0100 | ((apndp & 0b1) << 3) | (addr & 0b11) + val = 0b0000_0100 | ((apndp & 0b1) << 3) | (((addr >> 2) & 1) << 1) \ + | ((addr >> 3) & 1) self.reg_cmd.write(val) return (self.status(), self.rdata()) @@ -1680,8 +1681,9 @@ def debug_power_up(self, retry=10): """ Fully powers up the debug interface by writing to the CRTL/STAT register. """ - self.clear_errors() self.write(0, 0x4, (1 << 28) | (1 << 30)) + self.clear_errors() + self.read(0, 0) for _ in range(retry): (status, ctrl_stat) = self.read(0, 0x4) if ((ctrl_stat >> 29) & 0x1) == 1 and ((ctrl_stat >> 31) & 0x1) == 1: @@ -1698,7 +1700,7 @@ def rdata(self): """ Retrieve the data read by the last emitted Read transaction. """ - return int.from_bytes(self.reg_rdata.read(), 'little') | \ + return int.from_bytes(self.reg_rdata.read(), 'little') << 0 | \ int.from_bytes(self.reg_rdata.read(), 'little') << 8 | \ int.from_bytes(self.reg_rdata.read(), 'little') << 16 | \ int.from_bytes(self.reg_rdata.read(), 'little') << 24 From f1e40b815a9f60531f3d9e32531f15492a95e13a Mon Sep 17 00:00:00 2001 From: cchr Date: Tue, 27 Aug 2024 12:00:44 +0200 Subject: [PATCH 08/24] Take review comments into account for the API --- api/scaffold/__init__.py | 23 ++++++++-------- api/tests/test_swd.py | 59 ---------------------------------------- 2 files changed, 11 insertions(+), 71 deletions(-) delete mode 100644 api/tests/test_swd.py diff --git a/api/scaffold/__init__.py b/api/scaffold/__init__.py index 5625789..4934d0c 100644 --- a/api/scaffold/__init__.py +++ b/api/scaffold/__init__.py @@ -1663,11 +1663,14 @@ def write(self, apndp, addr, wdata: int): :param addr: Address of the register. :param wdata: 32-bit integer to write into the register. """ - val = 0b0000_0000 | ((apndp & 0b1) << 3) | (addr & 0b11) - self.reg_wdata.write(wdata & 0xff) - self.reg_wdata.write((wdata >> 8) & 0xff) - self.reg_wdata.write((wdata >> 16) & 0xff) - self.reg_wdata.write((wdata >> 24) & 0xff) + val = 0b0000_0000 | ((apndp & 0b1) << 3) | (((addr >> 2) & 1) << 1) \ + | ((addr >> 3) & 1) + wdata_bytes = [ + wdata & 0xff, + (wdata >> 8) & 0xff, + (wdata >> 16) & 0xff, + (wdata >> 24) & 0xff] + self.reg_wdata.write(bytearray(wdata_bytes)) self.reg_cmd.write(val) return self.status() @@ -1694,16 +1697,13 @@ def status(self): """ Retrieve the status of the last emitted SWD transaction. """ - return SWDStatus(int.from_bytes(self.reg_status.read(), 'little') & 0b11) + return SWDStatus(self.reg_status.read()[0] & 0b11) def rdata(self): """ Retrieve the data read by the last emitted Read transaction. """ - return int.from_bytes(self.reg_rdata.read(), 'little') << 0 | \ - int.from_bytes(self.reg_rdata.read(), 'little') << 8 | \ - int.from_bytes(self.reg_rdata.read(), 'little') << 16 | \ - int.from_bytes(self.reg_rdata.read(), 'little') << 24 + return int.from_bytes(self.reg_rdata.read(4), 'little') class IOMode(Enum): @@ -2306,8 +2306,7 @@ def connect( # Declare the swd module if self.version >= parse_version("0.10"): - self.swd = swd = SWD(self) - self.__setattr__("swd", swd) + self.swd = SWD(self) # Create the ISO7816 module self.iso7816 = ISO7816(self) diff --git a/api/tests/test_swd.py b/api/tests/test_swd.py deleted file mode 100644 index 5346293..0000000 --- a/api/tests/test_swd.py +++ /dev/null @@ -1,59 +0,0 @@ -# This file is part of Scaffold -# -# Scaffold is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see . -# -# -# Copyright 2024 Ledger SAS - -# from scaffold import Scaffold, Pull - - -# def test_dut_connection_ok(): -# scaffold = Scaffold("/dev/ttyUSB3") -# swd = scaffold.swd -# swd.swclk >> scaffold.d0 -# swd.swd_out >> scaffold.d1 -# swd.swd_in << scaffold.d1 -# scaffold.d0.pull = Pull.UP -# scaffold.d1.pull = Pull.UP -# -# status = swd.reset() -# print(f"status after: {status}") - - -# def test_read(): -# scaffold = Scaffold("/dev/ttyUSB3") -# swd = scaffold.swd -# swd.swclk >> scaffold.d0 -# swd.swd_out >> scaffold.d1 -# swd.swd_in << scaffold.d1 -# scaffold.d0.pull = Pull.UP -# scaffold.d1.pull = Pull.UP -# -# (status, rdata) = swd.read(0, 0) -# print(f"status after: {status}") -# print(f"rdata: {hex(rdata)}") - - -# def test_write(): -# scaffold = Scaffold("/dev/ttyUSB3") -# swd = scaffold.swd -# swd.swclk >> scaffold.d0 -# swd.swd_out >> scaffold.d1 -# swd.swd_in << scaffold.d1 -# scaffold.d0.pull = Pull.UP -# scaffold.d1.pull = Pull.UP -# -# status = swd.write(0, 0, 0b11010) -# print(f"status after: {status}") From 80ed0602447edd39d0f3fea3b83277a6bf2dde7c Mon Sep 17 00:00:00 2001 From: Michael Mouchous <99665078+mmouchous-ledger@users.noreply.github.com> Date: Fri, 30 Aug 2024 10:05:44 +0000 Subject: [PATCH 09/24] Remove the type() on trigger --- api/scaffold/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/scaffold/__init__.py b/api/scaffold/__init__.py index b90f88e..1272427 100644 --- a/api/scaffold/__init__.py +++ b/api/scaffold/__init__.py @@ -1117,11 +1117,11 @@ def raw_transaction(self, data, read_size, trigger=None): # Verify trigger parameter before doing anything t_start = False t_end = False - if isinstance(type(trigger), int): + if isinstance(trigger, int): if trigger not in range(2): raise ValueError("Invalid trigger parameter") t_start = trigger == 1 - elif isinstance(type(trigger), str): + elif isinstance(trigger, str): t_start = "a" in trigger t_end = "b" in trigger else: From 259162f6a28626814759f465c5c550e0c956f307 Mon Sep 17 00:00:00 2001 From: mmouchous-ledger Date: Fri, 30 Aug 2024 12:59:24 +0200 Subject: [PATCH 10/24] Bump pip package version --- api/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/setup.py b/api/setup.py index 291ed18..fd6b060 100755 --- a/api/setup.py +++ b/api/setup.py @@ -26,7 +26,7 @@ setup( name="donjon-scaffold", - version="0.9.0", + version="0.9.1", author="Olivier Heriveaux", description="Python3 API for the Scaffold board", long_description=long_description, From dbeb8a6c6c6833c5b3ae6205378d483a40340042 Mon Sep 17 00:00:00 2001 From: mmouchous-ledger Date: Fri, 30 Aug 2024 13:16:06 +0200 Subject: [PATCH 11/24] Fixing #23 --- api/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/setup.py b/api/setup.py index fd6b060..bd09740 100755 --- a/api/setup.py +++ b/api/setup.py @@ -32,7 +32,7 @@ long_description=long_description, long_description_content_type="text/markdown", url="https://github.com/Ledger-Donjon/scaffold", - install_requires=["pyserial", "crcmod", "requests"], + install_requires=["pyserial", "crcmod", "requests", "packaging"], packages=find_packages(), python_requires=">=3.6", ) From e51bb1179bb766f68b06d9361ba4d53597690b8c Mon Sep 17 00:00:00 2001 From: mmouchous-ledger Date: Fri, 30 Aug 2024 13:19:02 +0200 Subject: [PATCH 12/24] Add packaging library to requirements.txt (for documentation) --- docs/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/requirements.txt b/docs/requirements.txt index 22117ad..af3c4fe 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -2,5 +2,6 @@ sphinxcontrib-wavedrom sphinxcontrib-spelling matplotlib pyserial +packaging crcmod sphinx-rtd-theme>=1.3.0rc1 From 4038cedb4b1e2d29e12bef5618f54ad4cf0cb42d Mon Sep 17 00:00:00 2001 From: mmouchous-ledger Date: Fri, 30 Aug 2024 13:26:41 +0200 Subject: [PATCH 13/24] Bump version 10.0 --- api/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/setup.py b/api/setup.py index bd09740..d77f770 100755 --- a/api/setup.py +++ b/api/setup.py @@ -26,7 +26,7 @@ setup( name="donjon-scaffold", - version="0.9.1", + version="0.10.0", author="Olivier Heriveaux", description="Python3 API for the Scaffold board", long_description=long_description, From afc5707de1f7995aa031ba4bf544579086d27054 Mon Sep 17 00:00:00 2001 From: cchr Date: Tue, 3 Sep 2024 16:17:52 +0200 Subject: [PATCH 14/24] Use to_bytes for splitting wdata, as per review recommendation --- api/scaffold/__init__.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/api/scaffold/__init__.py b/api/scaffold/__init__.py index e153d53..509f650 100644 --- a/api/scaffold/__init__.py +++ b/api/scaffold/__init__.py @@ -1665,12 +1665,8 @@ def write(self, apndp, addr, wdata: int): """ val = 0b0000_0000 | ((apndp & 0b1) << 3) | (((addr >> 2) & 1) << 1) \ | ((addr >> 3) & 1) - wdata_bytes = [ - wdata & 0xff, - (wdata >> 8) & 0xff, - (wdata >> 16) & 0xff, - (wdata >> 24) & 0xff] - self.reg_wdata.write(bytearray(wdata_bytes)) + wdata_bytes = wdata.to_bytes(4, "little") + self.reg_wdata.write(wdata_bytes) self.reg_cmd.write(val) return self.status() From 44031a4e553535691cdba778cbcc0159725faf22 Mon Sep 17 00:00:00 2001 From: cchr Date: Tue, 3 Sep 2024 16:19:20 +0200 Subject: [PATCH 15/24] Remove always_ready when it is already implied by the use of always_enabled, as per review comment --- fpga-arch/bsv/Prescaler.bsv | 2 +- fpga-arch/bsv/SWD.bsv | 2 +- fpga-arch/bsv/SWDInner.bsv | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fpga-arch/bsv/Prescaler.bsv b/fpga-arch/bsv/Prescaler.bsv index 0fca07b..05e22d9 100644 --- a/fpga-arch/bsv/Prescaler.bsv +++ b/fpga-arch/bsv/Prescaler.bsv @@ -20,7 +20,7 @@ package Prescaler; import Counter::*; -(* always_ready, always_enabled *) +(* always_enabled *) interface Prescaler#(numeric type n); method Bool rising; method Bool falling; diff --git a/fpga-arch/bsv/SWD.bsv b/fpga-arch/bsv/SWD.bsv index 01f6df1..4b861bb 100644 --- a/fpga-arch/bsv/SWD.bsv +++ b/fpga-arch/bsv/SWD.bsv @@ -23,7 +23,7 @@ import Vector::*; import StmtFSM::*; import ClientServer::*; -(* always_ready, always_enabled *) +(* always_enabled *) interface ScaffoldBus; // bus_in_t (* prefix="" *) method Action address((* port="address" *) Bit#(16) a); diff --git a/fpga-arch/bsv/SWDInner.bsv b/fpga-arch/bsv/SWDInner.bsv index deae54b..40ba887 100644 --- a/fpga-arch/bsv/SWDInner.bsv +++ b/fpga-arch/bsv/SWDInner.bsv @@ -91,7 +91,7 @@ typedef union tagged { /// The peripheral-facing pins of the SWD controller, /// with swdio split into swd_in and swd_out. -(* always_ready, always_enabled *) +(* always_enabled *) interface SWDControllerPins; (* prefix="" *) method Bit#(1) swclk; (* prefix="" *) method Action swd_in((* port="swd_in" *) Bit#(1) b); @@ -105,8 +105,8 @@ endinterface interface SWDController#(numeric type clk_divider); method Action reset; interface Server#(Request, Response) rw; - (* always_ready, always_enabled *) method Bool ready; - (* always_ready, always_enabled *) interface SWDControllerPins pins; + (* always_enabled *) method Bool ready; + (* always_enabled *) interface SWDControllerPins pins; endinterface module mkSWDController (SWDController#(clk_divider)) From fd50d0071c8b69efdc1e114f7b1f77c759c9a71a Mon Sep 17 00:00:00 2001 From: cchr Date: Tue, 3 Sep 2024 16:20:05 +0200 Subject: [PATCH 16/24] Fix typo, as per review comment --- fpga-arch/bsv/Counter.v | 1 - 1 file changed, 1 deletion(-) diff --git a/fpga-arch/bsv/Counter.v b/fpga-arch/bsv/Counter.v index 87ddb51..0259385 100644 --- a/fpga-arch/bsv/Counter.v +++ b/fpga-arch/bsv/Counter.v @@ -33,7 +33,6 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -# `ifdef BSV_ASSIGNMENT_DELAY `else `define BSV_ASSIGNMENT_DELAY From b2a7b0f60c82d928d3cc62a342d496d1e2849be1 Mon Sep 17 00:00:00 2001 From: cchr Date: Tue, 3 Sep 2024 16:35:38 +0200 Subject: [PATCH 17/24] Take review comments into account --- fpga-arch/bsv/SWD.bsv | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/fpga-arch/bsv/SWD.bsv b/fpga-arch/bsv/SWD.bsv index 4b861bb..e37ab71 100644 --- a/fpga-arch/bsv/SWD.bsv +++ b/fpga-arch/bsv/SWD.bsv @@ -77,8 +77,6 @@ module swd_module (ScaffoldSWDModule); Reg#(Bit#(8)) bus_reg_rdata <- mkReg(0); Reg#(Bit#(8)) bus_reg_status <- mkReg(0); - Reg#(Bit#(2)) reg_rdata_cnt <- mkReg(0); - Reg#(Vector#(4, Bit#(8))) rdata <- mkReg(unpack(0)); Reg#(Status) status <- mkReg(unpack(0)); Reg#(Vector#(4, Bit#(8))) wdata <- mkReg(unpack(0)); @@ -87,22 +85,23 @@ module swd_module (ScaffoldSWDModule); Reg#(Bool) ready <- mkReg(False); Reg#(State) state <- mkReg(IDLE); - rule do_bus_read (bus_read == 1); - case ({bus_en_rdata, bus_en_status}) matches - 2'b10: - begin - bus_reg_rdata <= rdata[reg_rdata_cnt]; - reg_rdata_cnt <= reg_rdata_cnt + 1; - end - 2'b01: bus_reg_status <= {pack(state == IDLE), 5'b0, pack(status)}; - endcase + rule do_bus_read_rdata ((bus_read == 1) && (bus_en_rdata == 1) && (state != RW)); + bus_reg_rdata <= rdata[0]; + rdata <= shiftInAtN(rdata, 0); + endrule + + rule do_bus_read_status ((bus_read == 1) && (bus_en_status == 1)); + bus_reg_status <= {pack(state == IDLE), 5'b0, pack(status)}; endrule rule do_bus_write ((bus_write == 1) && (state == IDLE)); - case ({bus_en_wdata, bus_en_cmd}) matches - 2'b10: wdata <= shiftInAt0(wdata, bus_write_data); - 2'b01: cmd <= tagged Valid(unpack(bus_write_data)); - endcase + if (bus_en_wdata == 1) begin + wdata <= shiftInAt0(wdata, bus_write_data); + end + + if (bus_en_cmd == 1) begin + cmd <= tagged Valid(unpack(bus_write_data)); + end endrule rule do_ready; From a63e0d4a457e649f83408f280a2e2ad3bc13ecb4 Mon Sep 17 00:00:00 2001 From: cchr Date: Tue, 3 Sep 2024 16:39:13 +0200 Subject: [PATCH 18/24] Prefer mkRegA to mkReg --- fpga-arch/bsv/SWD.bsv | 16 ++++++++-------- fpga-arch/bsv/SWDInner.bsv | 12 ++++++------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/fpga-arch/bsv/SWD.bsv b/fpga-arch/bsv/SWD.bsv index e37ab71..928b2b6 100644 --- a/fpga-arch/bsv/SWD.bsv +++ b/fpga-arch/bsv/SWD.bsv @@ -74,16 +74,16 @@ module swd_module (ScaffoldSWDModule); Wire#(Bit#(1)) bus_en_cmd <- mkDWire(0); Wire#(Bit#(1)) bus_en_status <- mkDWire(0); - Reg#(Bit#(8)) bus_reg_rdata <- mkReg(0); - Reg#(Bit#(8)) bus_reg_status <- mkReg(0); + Reg#(Bit#(8)) bus_reg_rdata <- mkRegA(0); + Reg#(Bit#(8)) bus_reg_status <- mkRegA(0); - Reg#(Vector#(4, Bit#(8))) rdata <- mkReg(unpack(0)); - Reg#(Status) status <- mkReg(unpack(0)); - Reg#(Vector#(4, Bit#(8))) wdata <- mkReg(unpack(0)); - Reg#(Maybe#(Cmd)) cmd <- mkReg(tagged Invalid); + Reg#(Vector#(4, Bit#(8))) rdata <- mkRegA(unpack(0)); + Reg#(Status) status <- mkRegA(unpack(0)); + Reg#(Vector#(4, Bit#(8))) wdata <- mkRegA(unpack(0)); + Reg#(Maybe#(Cmd)) cmd <- mkRegA(tagged Invalid); - Reg#(Bool) ready <- mkReg(False); - Reg#(State) state <- mkReg(IDLE); + Reg#(Bool) ready <- mkRegA(False); + Reg#(State) state <- mkRegA(IDLE); rule do_bus_read_rdata ((bus_read == 1) && (bus_en_rdata == 1) && (state != RW)); bus_reg_rdata <= rdata[0]; diff --git a/fpga-arch/bsv/SWDInner.bsv b/fpga-arch/bsv/SWDInner.bsv index 40ba887..705c543 100644 --- a/fpga-arch/bsv/SWDInner.bsv +++ b/fpga-arch/bsv/SWDInner.bsv @@ -134,17 +134,17 @@ module mkSWDController (SWDController#(clk_divider)) Prescaler#(clk_divider) prescaler <- mkPrescaler(); // Status and ACK of the current transaction. - Reg#(Maybe#(Status)) status <- mkReg(tagged Invalid); - Reg#(Vector#(3, Bit#(1))) ack <- mkReg(unpack(0)); + Reg#(Maybe#(Status)) status <- mkRegA(tagged Invalid); + Reg#(Vector#(3, Bit#(1))) ack <- mkRegA(unpack(0)); // Controller pins. - Reg#(Bit#(1)) swd_out <- mkReg(0); + Reg#(Bit#(1)) swd_out <- mkRegA(0); Wire#(Bit#(1)) swd_in <- mkDWire(0); - Reg#(Bool) out_en <- mkReg(True); - Reg#(Bit#(1)) swclk <- mkReg(0); + Reg#(Bool) out_en <- mkRegA(True); + Reg#(Bit#(1)) swclk <- mkRegA(0); // Inner state. - Reg#(State) state <- mkReg(IDLE); + Reg#(State) state <- mkRegA(IDLE); Reg#(Bool) rnw <- mkRegU; Reg#(Vector#(8, Bit#(1))) packet <- mkRegU; Reg#(Vector#(33, Bit#(1))) data <- mkRegU; From 407f8c19bb31bcf5788317d67f0b18c5a8c778a2 Mon Sep 17 00:00:00 2001 From: cchr Date: Tue, 3 Sep 2024 16:40:33 +0200 Subject: [PATCH 19/24] Update swd_module.v --- fpga-arch/swd_module.v | 457 ++++++++++++++++++++--------------------- 1 file changed, 222 insertions(+), 235 deletions(-) diff --git a/fpga-arch/swd_module.v b/fpga-arch/swd_module.v index 5daa068..8034ab5 100644 --- a/fpga-arch/swd_module.v +++ b/fpga-arch/swd_module.v @@ -1,7 +1,7 @@ // // Generated by Bluespec Compiler, version 2024.01-9-gc481d7f5 (build c481d7f5) // -// On Mon Jul 29 18:28:06 CEST 2024 +// On Tue Sep 3 16:39:37 CEST 2024 // // // Ports: @@ -124,7 +124,7 @@ module swd_module(CLK, // register bus_reg_rdata reg [7 : 0] bus_reg_rdata; - reg [7 : 0] bus_reg_rdata$D_IN; + wire [7 : 0] bus_reg_rdata$D_IN; wire bus_reg_rdata$EN; // register bus_reg_status @@ -146,11 +146,6 @@ module swd_module(CLK, reg ready; wire ready$D_IN, ready$EN; - // register reg_rdata_cnt - reg [1 : 0] reg_rdata_cnt; - wire [1 : 0] reg_rdata_cnt$D_IN; - wire reg_rdata_cnt$EN; - // register state reg [1 : 0] state; reg [1 : 0] state$D_IN; @@ -225,7 +220,8 @@ module swd_module(CLK, swd_controller_prescaler_ctr$SETF; // rule scheduling signals - wire WILL_FIRE_RL_do_bus_write, + wire WILL_FIRE_RL_do_bus_read_rdata, + WILL_FIRE_RL_do_bus_write, WILL_FIRE_RL_do_idle, WILL_FIRE_RL_do_reset, WILL_FIRE_RL_do_rw; @@ -235,6 +231,7 @@ module swd_module(CLK, wire [32 : 0] MUX_swd_controller_data$write_1__VAL_1, MUX_swd_controller_data$write_1__VAL_2, MUX_swd_controller_data$write_1__VAL_3; + wire [31 : 0] MUX_rdata$write_1__VAL_1, MUX_rdata$write_1__VAL_2; wire [8 : 0] MUX_cmd$write_1__VAL_1; wire [7 : 0] MUX_swd_controller_packet$write_1__VAL_2, MUX_swd_controller_packet$write_1__VAL_3; @@ -278,77 +275,77 @@ module swd_module(CLK, // remaining internal signals wire [15 : 0] _0xE79E__q2; - wire [6 : 0] i__h1357, x__h14817; + wire [6 : 0] i__h1354, x__h14814; wire [1 : 0] cmd_BITS_1_TO_0__q1; wire swd_controller_cnt_2_ULE_8___d35, - swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d307, - x__h1338, - x__h19311, - x__h19324, - x__h19326, - x__h20464, - x__h20477, - z__h23711, - z__h23718, - z__h23725, - z__h23732, - z__h23739, - z__h23746, - z__h23753, - z__h23760, - z__h23767, - z__h23774, - z__h23781, - z__h23788, - z__h23795, - z__h23802, - z__h23809, - z__h23816, - z__h23823, - z__h23830, - z__h23837, - z__h23844, - z__h23851, - z__h23858, - z__h23865, - z__h23872, - z__h23879, - z__h23886, - z__h23893, - z__h23900, - z__h23907, - z__h23914, - z__h34272, - z__h34279, - z__h34286, - z__h34293, - z__h34300, - z__h34307, - z__h34314, - z__h34321, - z__h34328, - z__h34335, - z__h34342, - z__h34349, - z__h34356, - z__h34363, - z__h34370, - z__h34377, - z__h34384, - z__h34391, - z__h34398, - z__h34405, - z__h34412, - z__h34419, - z__h34426, - z__h34433, - z__h34440, - z__h34447, - z__h34454, - z__h34461, - z__h34468, - z__h34475, - z__h34482; + swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d300, + x__h1335, + x__h19897, + x__h19910, + x__h19912, + x__h21050, + x__h21063, + z__h24297, + z__h24304, + z__h24311, + z__h24318, + z__h24325, + z__h24332, + z__h24339, + z__h24346, + z__h24353, + z__h24360, + z__h24367, + z__h24374, + z__h24381, + z__h24388, + z__h24395, + z__h24402, + z__h24409, + z__h24416, + z__h24423, + z__h24430, + z__h24437, + z__h24444, + z__h24451, + z__h24458, + z__h24465, + z__h24472, + z__h24479, + z__h24486, + z__h24493, + z__h24500, + z__h34858, + z__h34865, + z__h34872, + z__h34879, + z__h34886, + z__h34893, + z__h34900, + z__h34907, + z__h34914, + z__h34921, + z__h34928, + z__h34935, + z__h34942, + z__h34949, + z__h34956, + z__h34963, + z__h34970, + z__h34977, + z__h34984, + z__h34991, + z__h34998, + z__h35005, + z__h35012, + z__h35019, + z__h35026, + z__h35033, + z__h35040, + z__h35047, + z__h35054, + z__h35061, + z__h35068; // value method bus_reg_rdata assign reg_rdata = bus_reg_rdata ; @@ -379,6 +376,9 @@ module swd_module(CLK, .SETF(swd_controller_prescaler_ctr$SETF), .Q_OUT(swd_controller_prescaler_ctr$Q_OUT)); + // rule RL_do_bus_read_rdata + assign WILL_FIRE_RL_do_bus_read_rdata = read && en_rdata && state != 2'd2 ; + // rule RL_do_bus_write assign WILL_FIRE_RL_do_bus_write = write && state == 2'd0 ; @@ -400,8 +400,7 @@ module swd_module(CLK, state == 2'd2 ; // inputs to muxes for submodule ports - assign MUX_cmd$write_1__SEL_1 = - WILL_FIRE_RL_do_bus_write && { en_wdata, en_cmd } == 2'b01 ; + assign MUX_cmd$write_1__SEL_1 = WILL_FIRE_RL_do_bus_write && en_cmd ; assign MUX_state$write_1__SEL_1 = WILL_FIRE_RL_do_reset && ready ; assign MUX_swd_controller_cnt$write_1__PSEL_1 = swd_controller_state == 4'd7 || swd_controller_state == 4'd1 || @@ -487,6 +486,13 @@ module swd_module(CLK, MUX_swd_controller_swd_out$write_1__PSEL_4 && swd_controller_prescaler_ctr$Q_OUT == 8'd0 ; assign MUX_cmd$write_1__VAL_1 = { 1'd1, write_data } ; + assign MUX_rdata$write_1__VAL_1 = { 8'd0, rdata[31:8] } ; + assign MUX_rdata$write_1__VAL_2 = + swd_controller_rnw ? + (swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d300 ? + 32'd0 : + swd_controller_data[31:0]) : + 32'd0 ; assign MUX_state$write_1__VAL_2 = cmd[7] ? 2'd1 : 2'd2 ; assign MUX_swd_controller_cnt$write_1__VAL_2 = (swd_controller_ack == 3'b100) ? 7'd33 : 7'd1 ; @@ -494,22 +500,22 @@ module swd_module(CLK, swd_controller_request_in$whas ? 7'd10 : 7'd126 ; assign MUX_swd_controller_cnt$write_1__VAL_5 = (swd_controller_prescaler_ctr$Q_OUT == 8'd0) ? - x__h14817 : + x__h14814 : 7'd33 ; assign MUX_swd_controller_cnt$write_1__VAL_6 = - (swd_controller_prescaler_ctr$Q_OUT == 8'd0) ? x__h14817 : 7'd1 ; + (swd_controller_prescaler_ctr$Q_OUT == 8'd0) ? x__h14814 : 7'd1 ; assign MUX_swd_controller_data$write_1__VAL_1 = { swd_in, swd_controller_data[32:1] } ; assign MUX_swd_controller_data$write_1__VAL_2 = { 1'd0, swd_controller_data[32:1] } ; assign MUX_swd_controller_data$write_1__VAL_3 = - { z__h23914 ^ wdata[7], + { z__h24500 ^ wdata[7], wdata[7:0], wdata[15:8], wdata[23:16], wdata[31:24] } ; assign MUX_swd_controller_packet$write_1__VAL_2 = - { 1'd1, cmd[3:0], cmd[2] ? x__h19311 : x__h20464, 2'd1 } ; + { 1'd1, cmd[3:0], cmd[2] ? x__h19897 : x__h21050, 2'd1 } ; assign MUX_swd_controller_packet$write_1__VAL_3 = { swd_controller_packet[6:0], 1'd0 } ; assign MUX_swd_controller_state$write_1__VAL_1 = @@ -529,7 +535,7 @@ module swd_module(CLK, end assign MUX_swd_controller_swd_out$write_1__VAL_2 = swd_controller_cnt > 7'd71 || swd_controller_cnt <= 7'd55 || - x__h1338 ; + x__h1335 ; assign MUX_swd_controller_swd_out$write_1__VAL_3 = swd_controller_cnt_2_ULE_8___d35 && swd_controller_packet[7] ; @@ -540,44 +546,28 @@ module swd_module(CLK, assign swd_controller_reset_in$whas = WILL_FIRE_RL_do_idle && cmd[7] ; // register bus_reg_rdata - always@(reg_rdata_cnt or rdata) - begin - case (reg_rdata_cnt) - 2'd0: bus_reg_rdata$D_IN = rdata[7:0]; - 2'd1: bus_reg_rdata$D_IN = rdata[15:8]; - 2'd2: bus_reg_rdata$D_IN = rdata[23:16]; - 2'd3: bus_reg_rdata$D_IN = rdata[31:24]; - endcase - end - assign bus_reg_rdata$EN = read && { en_rdata, en_status } == 2'b10 ; + assign bus_reg_rdata$D_IN = rdata[7:0] ; + assign bus_reg_rdata$EN = WILL_FIRE_RL_do_bus_read_rdata ; // register bus_reg_status assign bus_reg_status$D_IN = { state == 2'd0, 5'b0, status } ; - assign bus_reg_status$EN = read && { en_rdata, en_status } == 2'b01 ; + assign bus_reg_status$EN = read && en_status ; // register cmd assign cmd$D_IN = MUX_cmd$write_1__SEL_1 ? MUX_cmd$write_1__VAL_1 : 9'd170 ; - assign cmd$EN = - WILL_FIRE_RL_do_bus_write && { en_wdata, en_cmd } == 2'b01 || - WILL_FIRE_RL_do_rw ; + assign cmd$EN = WILL_FIRE_RL_do_bus_write && en_cmd || WILL_FIRE_RL_do_rw ; // register rdata assign rdata$D_IN = - swd_controller_rnw ? - (swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d307 ? - 32'd0 : - swd_controller_data[31:0]) : - 32'd0 ; - assign rdata$EN = WILL_FIRE_RL_do_rw ; + WILL_FIRE_RL_do_bus_read_rdata ? + MUX_rdata$write_1__VAL_1 : + MUX_rdata$write_1__VAL_2 ; + assign rdata$EN = WILL_FIRE_RL_do_bus_read_rdata || WILL_FIRE_RL_do_rw ; // register ready assign ready$D_IN = swd_controller_state == 4'd0 ; assign ready$EN = 1'd1 ; - // register reg_rdata_cnt - assign reg_rdata_cnt$D_IN = reg_rdata_cnt + 2'd1 ; - assign reg_rdata_cnt$EN = read && { en_rdata, en_status } == 2'b10 ; - // register state always@(MUX_state$write_1__SEL_1 or WILL_FIRE_RL_do_idle or @@ -597,7 +587,7 @@ module swd_module(CLK, // register status assign status$D_IN = swd_controller_rnw ? - (swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d307 ? + (swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d300 ? 2'd3 : swd_controller_status[1:0]) : swd_controller_status[1:0] ; @@ -611,7 +601,7 @@ module swd_module(CLK, // register swd_controller_cnt always@(MUX_swd_controller_cnt$write_1__SEL_1 or - x__h14817 or + x__h14814 or MUX_swd_controller_cnt$write_1__SEL_2 or MUX_swd_controller_cnt$write_1__VAL_2 or MUX_swd_controller_cnt$write_1__SEL_3 or @@ -624,7 +614,7 @@ module swd_module(CLK, begin case (1'b1) // synopsys parallel_case MUX_swd_controller_cnt$write_1__SEL_1: - swd_controller_cnt$D_IN = x__h14817; + swd_controller_cnt$D_IN = x__h14814; MUX_swd_controller_cnt$write_1__SEL_2: swd_controller_cnt$D_IN = MUX_swd_controller_cnt$write_1__VAL_2; MUX_swd_controller_cnt$write_1__SEL_3: swd_controller_cnt$D_IN = 7'd3; @@ -833,8 +823,7 @@ module swd_module(CLK, // register wdata assign wdata$D_IN = { wdata[23:0], write_data } ; - assign wdata$EN = - WILL_FIRE_RL_do_bus_write && { en_wdata, en_cmd } == 2'b10 ; + assign wdata$EN = WILL_FIRE_RL_do_bus_write && en_wdata ; // submodule swd_controller_prescaler_ctr assign swd_controller_prescaler_ctr$DATA_A = 8'h0 ; @@ -851,133 +840,83 @@ module swd_module(CLK, // remaining internal signals assign _0xE79E__q2 = 16'hE79E ; assign cmd_BITS_1_TO_0__q1 = cmd[1:0] ; - assign i__h1357 = 7'd71 - swd_controller_cnt ; + assign i__h1354 = 7'd71 - swd_controller_cnt ; assign swd_controller_cnt_2_ULE_8___d35 = swd_controller_cnt <= 7'd8 ; - assign swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d307 = - z__h34482 ^ swd_controller_data[32] ; - assign x__h1338 = _0xE79E__q2[i__h1357[3:0]] ; - assign x__h14817 = swd_controller_cnt - 7'd1 ; - assign x__h19311 = x__h19324 ^ cmd_BITS_1_TO_0__q1[1] ; - assign x__h19324 = x__h19326 ^ cmd_BITS_1_TO_0__q1[0] ; - assign x__h19326 = ~cmd[3] ; - assign x__h20464 = x__h20477 ^ cmd_BITS_1_TO_0__q1[1] ; - assign x__h20477 = cmd[3] ^ cmd_BITS_1_TO_0__q1[0] ; - assign z__h23711 = wdata[24] ^ wdata[25] ; - assign z__h23718 = z__h23711 ^ wdata[26] ; - assign z__h23725 = z__h23718 ^ wdata[27] ; - assign z__h23732 = z__h23725 ^ wdata[28] ; - assign z__h23739 = z__h23732 ^ wdata[29] ; - assign z__h23746 = z__h23739 ^ wdata[30] ; - assign z__h23753 = z__h23746 ^ wdata[31] ; - assign z__h23760 = z__h23753 ^ wdata[16] ; - assign z__h23767 = z__h23760 ^ wdata[17] ; - assign z__h23774 = z__h23767 ^ wdata[18] ; - assign z__h23781 = z__h23774 ^ wdata[19] ; - assign z__h23788 = z__h23781 ^ wdata[20] ; - assign z__h23795 = z__h23788 ^ wdata[21] ; - assign z__h23802 = z__h23795 ^ wdata[22] ; - assign z__h23809 = z__h23802 ^ wdata[23] ; - assign z__h23816 = z__h23809 ^ wdata[8] ; - assign z__h23823 = z__h23816 ^ wdata[9] ; - assign z__h23830 = z__h23823 ^ wdata[10] ; - assign z__h23837 = z__h23830 ^ wdata[11] ; - assign z__h23844 = z__h23837 ^ wdata[12] ; - assign z__h23851 = z__h23844 ^ wdata[13] ; - assign z__h23858 = z__h23851 ^ wdata[14] ; - assign z__h23865 = z__h23858 ^ wdata[15] ; - assign z__h23872 = z__h23865 ^ wdata[0] ; - assign z__h23879 = z__h23872 ^ wdata[1] ; - assign z__h23886 = z__h23879 ^ wdata[2] ; - assign z__h23893 = z__h23886 ^ wdata[3] ; - assign z__h23900 = z__h23893 ^ wdata[4] ; - assign z__h23907 = z__h23900 ^ wdata[5] ; - assign z__h23914 = z__h23907 ^ wdata[6] ; - assign z__h34272 = swd_controller_data[0] ^ swd_controller_data[1] ; - assign z__h34279 = z__h34272 ^ swd_controller_data[2] ; - assign z__h34286 = z__h34279 ^ swd_controller_data[3] ; - assign z__h34293 = z__h34286 ^ swd_controller_data[4] ; - assign z__h34300 = z__h34293 ^ swd_controller_data[5] ; - assign z__h34307 = z__h34300 ^ swd_controller_data[6] ; - assign z__h34314 = z__h34307 ^ swd_controller_data[7] ; - assign z__h34321 = z__h34314 ^ swd_controller_data[8] ; - assign z__h34328 = z__h34321 ^ swd_controller_data[9] ; - assign z__h34335 = z__h34328 ^ swd_controller_data[10] ; - assign z__h34342 = z__h34335 ^ swd_controller_data[11] ; - assign z__h34349 = z__h34342 ^ swd_controller_data[12] ; - assign z__h34356 = z__h34349 ^ swd_controller_data[13] ; - assign z__h34363 = z__h34356 ^ swd_controller_data[14] ; - assign z__h34370 = z__h34363 ^ swd_controller_data[15] ; - assign z__h34377 = z__h34370 ^ swd_controller_data[16] ; - assign z__h34384 = z__h34377 ^ swd_controller_data[17] ; - assign z__h34391 = z__h34384 ^ swd_controller_data[18] ; - assign z__h34398 = z__h34391 ^ swd_controller_data[19] ; - assign z__h34405 = z__h34398 ^ swd_controller_data[20] ; - assign z__h34412 = z__h34405 ^ swd_controller_data[21] ; - assign z__h34419 = z__h34412 ^ swd_controller_data[22] ; - assign z__h34426 = z__h34419 ^ swd_controller_data[23] ; - assign z__h34433 = z__h34426 ^ swd_controller_data[24] ; - assign z__h34440 = z__h34433 ^ swd_controller_data[25] ; - assign z__h34447 = z__h34440 ^ swd_controller_data[26] ; - assign z__h34454 = z__h34447 ^ swd_controller_data[27] ; - assign z__h34461 = z__h34454 ^ swd_controller_data[28] ; - assign z__h34468 = z__h34461 ^ swd_controller_data[29] ; - assign z__h34475 = z__h34468 ^ swd_controller_data[30] ; - assign z__h34482 = z__h34475 ^ swd_controller_data[31] ; + assign swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d300 = + z__h35068 ^ swd_controller_data[32] ; + assign x__h1335 = _0xE79E__q2[i__h1354[3:0]] ; + assign x__h14814 = swd_controller_cnt - 7'd1 ; + assign x__h19897 = x__h19910 ^ cmd_BITS_1_TO_0__q1[1] ; + assign x__h19910 = x__h19912 ^ cmd_BITS_1_TO_0__q1[0] ; + assign x__h19912 = ~cmd[3] ; + assign x__h21050 = x__h21063 ^ cmd_BITS_1_TO_0__q1[1] ; + assign x__h21063 = cmd[3] ^ cmd_BITS_1_TO_0__q1[0] ; + assign z__h24297 = wdata[24] ^ wdata[25] ; + assign z__h24304 = z__h24297 ^ wdata[26] ; + assign z__h24311 = z__h24304 ^ wdata[27] ; + assign z__h24318 = z__h24311 ^ wdata[28] ; + assign z__h24325 = z__h24318 ^ wdata[29] ; + assign z__h24332 = z__h24325 ^ wdata[30] ; + assign z__h24339 = z__h24332 ^ wdata[31] ; + assign z__h24346 = z__h24339 ^ wdata[16] ; + assign z__h24353 = z__h24346 ^ wdata[17] ; + assign z__h24360 = z__h24353 ^ wdata[18] ; + assign z__h24367 = z__h24360 ^ wdata[19] ; + assign z__h24374 = z__h24367 ^ wdata[20] ; + assign z__h24381 = z__h24374 ^ wdata[21] ; + assign z__h24388 = z__h24381 ^ wdata[22] ; + assign z__h24395 = z__h24388 ^ wdata[23] ; + assign z__h24402 = z__h24395 ^ wdata[8] ; + assign z__h24409 = z__h24402 ^ wdata[9] ; + assign z__h24416 = z__h24409 ^ wdata[10] ; + assign z__h24423 = z__h24416 ^ wdata[11] ; + assign z__h24430 = z__h24423 ^ wdata[12] ; + assign z__h24437 = z__h24430 ^ wdata[13] ; + assign z__h24444 = z__h24437 ^ wdata[14] ; + assign z__h24451 = z__h24444 ^ wdata[15] ; + assign z__h24458 = z__h24451 ^ wdata[0] ; + assign z__h24465 = z__h24458 ^ wdata[1] ; + assign z__h24472 = z__h24465 ^ wdata[2] ; + assign z__h24479 = z__h24472 ^ wdata[3] ; + assign z__h24486 = z__h24479 ^ wdata[4] ; + assign z__h24493 = z__h24486 ^ wdata[5] ; + assign z__h24500 = z__h24493 ^ wdata[6] ; + assign z__h34858 = swd_controller_data[0] ^ swd_controller_data[1] ; + assign z__h34865 = z__h34858 ^ swd_controller_data[2] ; + assign z__h34872 = z__h34865 ^ swd_controller_data[3] ; + assign z__h34879 = z__h34872 ^ swd_controller_data[4] ; + assign z__h34886 = z__h34879 ^ swd_controller_data[5] ; + assign z__h34893 = z__h34886 ^ swd_controller_data[6] ; + assign z__h34900 = z__h34893 ^ swd_controller_data[7] ; + assign z__h34907 = z__h34900 ^ swd_controller_data[8] ; + assign z__h34914 = z__h34907 ^ swd_controller_data[9] ; + assign z__h34921 = z__h34914 ^ swd_controller_data[10] ; + assign z__h34928 = z__h34921 ^ swd_controller_data[11] ; + assign z__h34935 = z__h34928 ^ swd_controller_data[12] ; + assign z__h34942 = z__h34935 ^ swd_controller_data[13] ; + assign z__h34949 = z__h34942 ^ swd_controller_data[14] ; + assign z__h34956 = z__h34949 ^ swd_controller_data[15] ; + assign z__h34963 = z__h34956 ^ swd_controller_data[16] ; + assign z__h34970 = z__h34963 ^ swd_controller_data[17] ; + assign z__h34977 = z__h34970 ^ swd_controller_data[18] ; + assign z__h34984 = z__h34977 ^ swd_controller_data[19] ; + assign z__h34991 = z__h34984 ^ swd_controller_data[20] ; + assign z__h34998 = z__h34991 ^ swd_controller_data[21] ; + assign z__h35005 = z__h34998 ^ swd_controller_data[22] ; + assign z__h35012 = z__h35005 ^ swd_controller_data[23] ; + assign z__h35019 = z__h35012 ^ swd_controller_data[24] ; + assign z__h35026 = z__h35019 ^ swd_controller_data[25] ; + assign z__h35033 = z__h35026 ^ swd_controller_data[26] ; + assign z__h35040 = z__h35033 ^ swd_controller_data[27] ; + assign z__h35047 = z__h35040 ^ swd_controller_data[28] ; + assign z__h35054 = z__h35047 ^ swd_controller_data[29] ; + assign z__h35061 = z__h35054 ^ swd_controller_data[30] ; + assign z__h35068 = z__h35061 ^ swd_controller_data[31] ; // handling of inlined registers always@(posedge CLK) begin - if (RST_N == `BSV_RESET_VALUE) - begin - bus_reg_rdata <= `BSV_ASSIGNMENT_DELAY 8'd0; - bus_reg_status <= `BSV_ASSIGNMENT_DELAY 8'd0; - cmd <= `BSV_ASSIGNMENT_DELAY 9'd170; - rdata <= `BSV_ASSIGNMENT_DELAY 32'd0; - ready <= `BSV_ASSIGNMENT_DELAY 1'd0; - reg_rdata_cnt <= `BSV_ASSIGNMENT_DELAY 2'd0; - state <= `BSV_ASSIGNMENT_DELAY 2'd0; - status <= `BSV_ASSIGNMENT_DELAY 2'd0; - swd_controller_ack <= `BSV_ASSIGNMENT_DELAY 3'd0; - swd_controller_out_en <= `BSV_ASSIGNMENT_DELAY 1'd1; - swd_controller_state <= `BSV_ASSIGNMENT_DELAY 4'd0; - swd_controller_status <= `BSV_ASSIGNMENT_DELAY 3'd2; - swd_controller_swclk <= `BSV_ASSIGNMENT_DELAY 1'd0; - swd_controller_swd_out <= `BSV_ASSIGNMENT_DELAY 1'd0; - wdata <= `BSV_ASSIGNMENT_DELAY 32'd0; - end - else - begin - if (bus_reg_rdata$EN) - bus_reg_rdata <= `BSV_ASSIGNMENT_DELAY bus_reg_rdata$D_IN; - if (bus_reg_status$EN) - bus_reg_status <= `BSV_ASSIGNMENT_DELAY bus_reg_status$D_IN; - if (cmd$EN) cmd <= `BSV_ASSIGNMENT_DELAY cmd$D_IN; - if (rdata$EN) rdata <= `BSV_ASSIGNMENT_DELAY rdata$D_IN; - if (ready$EN) ready <= `BSV_ASSIGNMENT_DELAY ready$D_IN; - if (reg_rdata_cnt$EN) - reg_rdata_cnt <= `BSV_ASSIGNMENT_DELAY reg_rdata_cnt$D_IN; - if (state$EN) state <= `BSV_ASSIGNMENT_DELAY state$D_IN; - if (status$EN) status <= `BSV_ASSIGNMENT_DELAY status$D_IN; - if (swd_controller_ack$EN) - swd_controller_ack <= `BSV_ASSIGNMENT_DELAY swd_controller_ack$D_IN; - if (swd_controller_out_en$EN) - swd_controller_out_en <= `BSV_ASSIGNMENT_DELAY - swd_controller_out_en$D_IN; - if (swd_controller_state$EN) - swd_controller_state <= `BSV_ASSIGNMENT_DELAY - swd_controller_state$D_IN; - if (swd_controller_status$EN) - swd_controller_status <= `BSV_ASSIGNMENT_DELAY - swd_controller_status$D_IN; - if (swd_controller_swclk$EN) - swd_controller_swclk <= `BSV_ASSIGNMENT_DELAY - swd_controller_swclk$D_IN; - if (swd_controller_swd_out$EN) - swd_controller_swd_out <= `BSV_ASSIGNMENT_DELAY - swd_controller_swd_out$D_IN; - if (wdata$EN) wdata <= `BSV_ASSIGNMENT_DELAY wdata$D_IN; - end if (swd_controller_cnt$EN) swd_controller_cnt <= `BSV_ASSIGNMENT_DELAY swd_controller_cnt$D_IN; if (swd_controller_data$EN) @@ -989,6 +928,55 @@ module swd_module(CLK, swd_controller_rnw <= `BSV_ASSIGNMENT_DELAY swd_controller_rnw$D_IN; end + always@(posedge CLK or `BSV_RESET_EDGE RST_N) + if (RST_N == `BSV_RESET_VALUE) + begin + bus_reg_rdata <= `BSV_ASSIGNMENT_DELAY 8'd0; + bus_reg_status <= `BSV_ASSIGNMENT_DELAY 8'd0; + cmd <= `BSV_ASSIGNMENT_DELAY 9'd170; + rdata <= `BSV_ASSIGNMENT_DELAY 32'd0; + ready <= `BSV_ASSIGNMENT_DELAY 1'd0; + state <= `BSV_ASSIGNMENT_DELAY 2'd0; + status <= `BSV_ASSIGNMENT_DELAY 2'd0; + swd_controller_ack <= `BSV_ASSIGNMENT_DELAY 3'd0; + swd_controller_out_en <= `BSV_ASSIGNMENT_DELAY 1'd1; + swd_controller_state <= `BSV_ASSIGNMENT_DELAY 4'd0; + swd_controller_status <= `BSV_ASSIGNMENT_DELAY 3'd2; + swd_controller_swclk <= `BSV_ASSIGNMENT_DELAY 1'd0; + swd_controller_swd_out <= `BSV_ASSIGNMENT_DELAY 1'd0; + wdata <= `BSV_ASSIGNMENT_DELAY 32'd0; + end + else + begin + if (bus_reg_rdata$EN) + bus_reg_rdata <= `BSV_ASSIGNMENT_DELAY bus_reg_rdata$D_IN; + if (bus_reg_status$EN) + bus_reg_status <= `BSV_ASSIGNMENT_DELAY bus_reg_status$D_IN; + if (cmd$EN) cmd <= `BSV_ASSIGNMENT_DELAY cmd$D_IN; + if (rdata$EN) rdata <= `BSV_ASSIGNMENT_DELAY rdata$D_IN; + if (ready$EN) ready <= `BSV_ASSIGNMENT_DELAY ready$D_IN; + if (state$EN) state <= `BSV_ASSIGNMENT_DELAY state$D_IN; + if (status$EN) status <= `BSV_ASSIGNMENT_DELAY status$D_IN; + if (swd_controller_ack$EN) + swd_controller_ack <= `BSV_ASSIGNMENT_DELAY swd_controller_ack$D_IN; + if (swd_controller_out_en$EN) + swd_controller_out_en <= `BSV_ASSIGNMENT_DELAY + swd_controller_out_en$D_IN; + if (swd_controller_state$EN) + swd_controller_state <= `BSV_ASSIGNMENT_DELAY + swd_controller_state$D_IN; + if (swd_controller_status$EN) + swd_controller_status <= `BSV_ASSIGNMENT_DELAY + swd_controller_status$D_IN; + if (swd_controller_swclk$EN) + swd_controller_swclk <= `BSV_ASSIGNMENT_DELAY + swd_controller_swclk$D_IN; + if (swd_controller_swd_out$EN) + swd_controller_swd_out <= `BSV_ASSIGNMENT_DELAY + swd_controller_swd_out$D_IN; + if (wdata$EN) wdata <= `BSV_ASSIGNMENT_DELAY wdata$D_IN; + end + // synopsys translate_off `ifdef BSV_NO_INITIAL_BLOCKS `else // not BSV_NO_INITIAL_BLOCKS @@ -999,7 +987,6 @@ module swd_module(CLK, cmd = 9'h0AA; rdata = 32'hAAAAAAAA; ready = 1'h0; - reg_rdata_cnt = 2'h2; state = 2'h2; status = 2'h2; swd_controller_ack = 3'h2; From d4a316e0860108752c88cd7b16b14e4970c6cc35 Mon Sep 17 00:00:00 2001 From: cchr Date: Wed, 4 Sep 2024 10:16:12 +0200 Subject: [PATCH 20/24] Reset prescaler when requests go in, and simplify out_en expression --- fpga-arch/bsv/Prescaler.bsv | 14 +- fpga-arch/bsv/SWDInner.bsv | 13 +- fpga-arch/swd_module.v | 293 ++++++++++++++++++------------------ 3 files changed, 161 insertions(+), 159 deletions(-) diff --git a/fpga-arch/bsv/Prescaler.bsv b/fpga-arch/bsv/Prescaler.bsv index 05e22d9..3471970 100644 --- a/fpga-arch/bsv/Prescaler.bsv +++ b/fpga-arch/bsv/Prescaler.bsv @@ -22,6 +22,7 @@ import Counter::*; (* always_enabled *) interface Prescaler#(numeric type n); + method Action reset; method Bool rising; method Bool falling; method Bool pre_rising; @@ -37,16 +38,15 @@ module mkPrescaler (Prescaler#(prescale)) Counter#(ctr_sz) ctr <- mkCounter(fromInteger(valueof(ctr_max))); - (* fire_when_enabled, no_implicit_conditions *) - rule count_dow(ctr.value > 0); + rule count_dow (ctr.value > 0); ctr.down(); endrule - (* fire_when_enabled, no_implicit_conditions *) - rule reset_count(ctr.value == 0); - ctr.setF(fromInteger(valueof(ctr_max))); - endrule - + rule reset_count (ctr.value == 0); + ctr.setF(fromInteger(valueof(ctr_max))); + endrule + + method reset = ctr.setF(fromInteger(valueof(ctr_max))); method rising = (ctr.value == 0); method pre_rising = (ctr.value == 1); method falling = (ctr.value == fromInteger(valueof(__a))); diff --git a/fpga-arch/bsv/SWDInner.bsv b/fpga-arch/bsv/SWDInner.bsv index 705c543..dfa5bf3 100644 --- a/fpga-arch/bsv/SWDInner.bsv +++ b/fpga-arch/bsv/SWDInner.bsv @@ -156,6 +156,12 @@ module mkSWDController (SWDController#(clk_divider)) PulseWire request_in <- mkPulseWire(); PulseWire reset_in <- mkPulseWire(); + rule do_prescaler; + if (request_in) begin + prescaler.reset(); + end + endrule + // Generate the SWD clock, whenever there is an // ongoing transaction. // Note that the polarity is inverted (the peripheral samples the IO line on rising edges of swclk) @@ -171,12 +177,7 @@ module mkSWDController (SWDController#(clk_divider)) // SWDIO is treated as an input only when in // the ACK or RDATA phase. rule do_out_en; - if ((state == RESET) || (state == PACKET) || (state == WDATA)) begin - out_en <= True; - end - else begin - out_en <= False; - end + out_en <= ((state == RESET) || (state == PACKET) || (state == WDATA)); endrule // Stop idling when a request has been received. diff --git a/fpga-arch/swd_module.v b/fpga-arch/swd_module.v index 8034ab5..07d8408 100644 --- a/fpga-arch/swd_module.v +++ b/fpga-arch/swd_module.v @@ -1,7 +1,7 @@ // // Generated by Bluespec Compiler, version 2024.01-9-gc481d7f5 (build c481d7f5) // -// On Tue Sep 3 16:39:37 CEST 2024 +// On Wed Sep 4 10:01:30 CEST 2024 // // // Ports: @@ -275,77 +275,77 @@ module swd_module(CLK, // remaining internal signals wire [15 : 0] _0xE79E__q2; - wire [6 : 0] i__h1354, x__h14814; + wire [6 : 0] i__h1364, x__h14824; wire [1 : 0] cmd_BITS_1_TO_0__q1; wire swd_controller_cnt_2_ULE_8___d35, swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d300, - x__h1335, - x__h19897, - x__h19910, - x__h19912, - x__h21050, - x__h21063, - z__h24297, - z__h24304, - z__h24311, - z__h24318, - z__h24325, - z__h24332, - z__h24339, - z__h24346, - z__h24353, - z__h24360, - z__h24367, - z__h24374, - z__h24381, - z__h24388, - z__h24395, - z__h24402, - z__h24409, - z__h24416, - z__h24423, - z__h24430, - z__h24437, - z__h24444, - z__h24451, - z__h24458, - z__h24465, - z__h24472, - z__h24479, - z__h24486, - z__h24493, - z__h24500, - z__h34858, - z__h34865, - z__h34872, - z__h34879, - z__h34886, - z__h34893, - z__h34900, - z__h34907, - z__h34914, - z__h34921, - z__h34928, - z__h34935, - z__h34942, - z__h34949, - z__h34956, - z__h34963, - z__h34970, - z__h34977, - z__h34984, - z__h34991, - z__h34998, - z__h35005, - z__h35012, - z__h35019, - z__h35026, - z__h35033, - z__h35040, - z__h35047, - z__h35054, - z__h35061, - z__h35068; + x__h1345, + x__h19907, + x__h19920, + x__h19922, + x__h21060, + x__h21073, + z__h24307, + z__h24314, + z__h24321, + z__h24328, + z__h24335, + z__h24342, + z__h24349, + z__h24356, + z__h24363, + z__h24370, + z__h24377, + z__h24384, + z__h24391, + z__h24398, + z__h24405, + z__h24412, + z__h24419, + z__h24426, + z__h24433, + z__h24440, + z__h24447, + z__h24454, + z__h24461, + z__h24468, + z__h24475, + z__h24482, + z__h24489, + z__h24496, + z__h24503, + z__h24510, + z__h34868, + z__h34875, + z__h34882, + z__h34889, + z__h34896, + z__h34903, + z__h34910, + z__h34917, + z__h34924, + z__h34931, + z__h34938, + z__h34945, + z__h34952, + z__h34959, + z__h34966, + z__h34973, + z__h34980, + z__h34987, + z__h34994, + z__h35001, + z__h35008, + z__h35015, + z__h35022, + z__h35029, + z__h35036, + z__h35043, + z__h35050, + z__h35057, + z__h35064, + z__h35071, + z__h35078; // value method bus_reg_rdata assign reg_rdata = bus_reg_rdata ; @@ -500,22 +500,22 @@ module swd_module(CLK, swd_controller_request_in$whas ? 7'd10 : 7'd126 ; assign MUX_swd_controller_cnt$write_1__VAL_5 = (swd_controller_prescaler_ctr$Q_OUT == 8'd0) ? - x__h14814 : + x__h14824 : 7'd33 ; assign MUX_swd_controller_cnt$write_1__VAL_6 = - (swd_controller_prescaler_ctr$Q_OUT == 8'd0) ? x__h14814 : 7'd1 ; + (swd_controller_prescaler_ctr$Q_OUT == 8'd0) ? x__h14824 : 7'd1 ; assign MUX_swd_controller_data$write_1__VAL_1 = { swd_in, swd_controller_data[32:1] } ; assign MUX_swd_controller_data$write_1__VAL_2 = { 1'd0, swd_controller_data[32:1] } ; assign MUX_swd_controller_data$write_1__VAL_3 = - { z__h24500 ^ wdata[7], + { z__h24510 ^ wdata[7], wdata[7:0], wdata[15:8], wdata[23:16], wdata[31:24] } ; assign MUX_swd_controller_packet$write_1__VAL_2 = - { 1'd1, cmd[3:0], cmd[2] ? x__h19897 : x__h21050, 2'd1 } ; + { 1'd1, cmd[3:0], cmd[2] ? x__h19907 : x__h21060, 2'd1 } ; assign MUX_swd_controller_packet$write_1__VAL_3 = { swd_controller_packet[6:0], 1'd0 } ; assign MUX_swd_controller_state$write_1__VAL_1 = @@ -535,7 +535,7 @@ module swd_module(CLK, end assign MUX_swd_controller_swd_out$write_1__VAL_2 = swd_controller_cnt > 7'd71 || swd_controller_cnt <= 7'd55 || - x__h1335 ; + x__h1345 ; assign MUX_swd_controller_swd_out$write_1__VAL_3 = swd_controller_cnt_2_ULE_8___d35 && swd_controller_packet[7] ; @@ -601,7 +601,7 @@ module swd_module(CLK, // register swd_controller_cnt always@(MUX_swd_controller_cnt$write_1__SEL_1 or - x__h14814 or + x__h14824 or MUX_swd_controller_cnt$write_1__SEL_2 or MUX_swd_controller_cnt$write_1__VAL_2 or MUX_swd_controller_cnt$write_1__SEL_3 or @@ -614,7 +614,7 @@ module swd_module(CLK, begin case (1'b1) // synopsys parallel_case MUX_swd_controller_cnt$write_1__SEL_1: - swd_controller_cnt$D_IN = x__h14814; + swd_controller_cnt$D_IN = x__h14824; MUX_swd_controller_cnt$write_1__SEL_2: swd_controller_cnt$D_IN = MUX_swd_controller_cnt$write_1__VAL_2; MUX_swd_controller_cnt$write_1__SEL_3: swd_controller_cnt$D_IN = 7'd3; @@ -835,83 +835,84 @@ module swd_module(CLK, swd_controller_prescaler_ctr$Q_OUT != 8'd0 ; assign swd_controller_prescaler_ctr$SETC = 1'b0 ; assign swd_controller_prescaler_ctr$SETF = + swd_controller_request_in$whas || swd_controller_prescaler_ctr$Q_OUT == 8'd0 ; // remaining internal signals assign _0xE79E__q2 = 16'hE79E ; assign cmd_BITS_1_TO_0__q1 = cmd[1:0] ; - assign i__h1354 = 7'd71 - swd_controller_cnt ; + assign i__h1364 = 7'd71 - swd_controller_cnt ; assign swd_controller_cnt_2_ULE_8___d35 = swd_controller_cnt <= 7'd8 ; assign swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d300 = - z__h35068 ^ swd_controller_data[32] ; - assign x__h1335 = _0xE79E__q2[i__h1354[3:0]] ; - assign x__h14814 = swd_controller_cnt - 7'd1 ; - assign x__h19897 = x__h19910 ^ cmd_BITS_1_TO_0__q1[1] ; - assign x__h19910 = x__h19912 ^ cmd_BITS_1_TO_0__q1[0] ; - assign x__h19912 = ~cmd[3] ; - assign x__h21050 = x__h21063 ^ cmd_BITS_1_TO_0__q1[1] ; - assign x__h21063 = cmd[3] ^ cmd_BITS_1_TO_0__q1[0] ; - assign z__h24297 = wdata[24] ^ wdata[25] ; - assign z__h24304 = z__h24297 ^ wdata[26] ; - assign z__h24311 = z__h24304 ^ wdata[27] ; - assign z__h24318 = z__h24311 ^ wdata[28] ; - assign z__h24325 = z__h24318 ^ wdata[29] ; - assign z__h24332 = z__h24325 ^ wdata[30] ; - assign z__h24339 = z__h24332 ^ wdata[31] ; - assign z__h24346 = z__h24339 ^ wdata[16] ; - assign z__h24353 = z__h24346 ^ wdata[17] ; - assign z__h24360 = z__h24353 ^ wdata[18] ; - assign z__h24367 = z__h24360 ^ wdata[19] ; - assign z__h24374 = z__h24367 ^ wdata[20] ; - assign z__h24381 = z__h24374 ^ wdata[21] ; - assign z__h24388 = z__h24381 ^ wdata[22] ; - assign z__h24395 = z__h24388 ^ wdata[23] ; - assign z__h24402 = z__h24395 ^ wdata[8] ; - assign z__h24409 = z__h24402 ^ wdata[9] ; - assign z__h24416 = z__h24409 ^ wdata[10] ; - assign z__h24423 = z__h24416 ^ wdata[11] ; - assign z__h24430 = z__h24423 ^ wdata[12] ; - assign z__h24437 = z__h24430 ^ wdata[13] ; - assign z__h24444 = z__h24437 ^ wdata[14] ; - assign z__h24451 = z__h24444 ^ wdata[15] ; - assign z__h24458 = z__h24451 ^ wdata[0] ; - assign z__h24465 = z__h24458 ^ wdata[1] ; - assign z__h24472 = z__h24465 ^ wdata[2] ; - assign z__h24479 = z__h24472 ^ wdata[3] ; - assign z__h24486 = z__h24479 ^ wdata[4] ; - assign z__h24493 = z__h24486 ^ wdata[5] ; - assign z__h24500 = z__h24493 ^ wdata[6] ; - assign z__h34858 = swd_controller_data[0] ^ swd_controller_data[1] ; - assign z__h34865 = z__h34858 ^ swd_controller_data[2] ; - assign z__h34872 = z__h34865 ^ swd_controller_data[3] ; - assign z__h34879 = z__h34872 ^ swd_controller_data[4] ; - assign z__h34886 = z__h34879 ^ swd_controller_data[5] ; - assign z__h34893 = z__h34886 ^ swd_controller_data[6] ; - assign z__h34900 = z__h34893 ^ swd_controller_data[7] ; - assign z__h34907 = z__h34900 ^ swd_controller_data[8] ; - assign z__h34914 = z__h34907 ^ swd_controller_data[9] ; - assign z__h34921 = z__h34914 ^ swd_controller_data[10] ; - assign z__h34928 = z__h34921 ^ swd_controller_data[11] ; - assign z__h34935 = z__h34928 ^ swd_controller_data[12] ; - assign z__h34942 = z__h34935 ^ swd_controller_data[13] ; - assign z__h34949 = z__h34942 ^ swd_controller_data[14] ; - assign z__h34956 = z__h34949 ^ swd_controller_data[15] ; - assign z__h34963 = z__h34956 ^ swd_controller_data[16] ; - assign z__h34970 = z__h34963 ^ swd_controller_data[17] ; - assign z__h34977 = z__h34970 ^ swd_controller_data[18] ; - assign z__h34984 = z__h34977 ^ swd_controller_data[19] ; - assign z__h34991 = z__h34984 ^ swd_controller_data[20] ; - assign z__h34998 = z__h34991 ^ swd_controller_data[21] ; - assign z__h35005 = z__h34998 ^ swd_controller_data[22] ; - assign z__h35012 = z__h35005 ^ swd_controller_data[23] ; - assign z__h35019 = z__h35012 ^ swd_controller_data[24] ; - assign z__h35026 = z__h35019 ^ swd_controller_data[25] ; - assign z__h35033 = z__h35026 ^ swd_controller_data[26] ; - assign z__h35040 = z__h35033 ^ swd_controller_data[27] ; - assign z__h35047 = z__h35040 ^ swd_controller_data[28] ; - assign z__h35054 = z__h35047 ^ swd_controller_data[29] ; - assign z__h35061 = z__h35054 ^ swd_controller_data[30] ; - assign z__h35068 = z__h35061 ^ swd_controller_data[31] ; + z__h35078 ^ swd_controller_data[32] ; + assign x__h1345 = _0xE79E__q2[i__h1364[3:0]] ; + assign x__h14824 = swd_controller_cnt - 7'd1 ; + assign x__h19907 = x__h19920 ^ cmd_BITS_1_TO_0__q1[1] ; + assign x__h19920 = x__h19922 ^ cmd_BITS_1_TO_0__q1[0] ; + assign x__h19922 = ~cmd[3] ; + assign x__h21060 = x__h21073 ^ cmd_BITS_1_TO_0__q1[1] ; + assign x__h21073 = cmd[3] ^ cmd_BITS_1_TO_0__q1[0] ; + assign z__h24307 = wdata[24] ^ wdata[25] ; + assign z__h24314 = z__h24307 ^ wdata[26] ; + assign z__h24321 = z__h24314 ^ wdata[27] ; + assign z__h24328 = z__h24321 ^ wdata[28] ; + assign z__h24335 = z__h24328 ^ wdata[29] ; + assign z__h24342 = z__h24335 ^ wdata[30] ; + assign z__h24349 = z__h24342 ^ wdata[31] ; + assign z__h24356 = z__h24349 ^ wdata[16] ; + assign z__h24363 = z__h24356 ^ wdata[17] ; + assign z__h24370 = z__h24363 ^ wdata[18] ; + assign z__h24377 = z__h24370 ^ wdata[19] ; + assign z__h24384 = z__h24377 ^ wdata[20] ; + assign z__h24391 = z__h24384 ^ wdata[21] ; + assign z__h24398 = z__h24391 ^ wdata[22] ; + assign z__h24405 = z__h24398 ^ wdata[23] ; + assign z__h24412 = z__h24405 ^ wdata[8] ; + assign z__h24419 = z__h24412 ^ wdata[9] ; + assign z__h24426 = z__h24419 ^ wdata[10] ; + assign z__h24433 = z__h24426 ^ wdata[11] ; + assign z__h24440 = z__h24433 ^ wdata[12] ; + assign z__h24447 = z__h24440 ^ wdata[13] ; + assign z__h24454 = z__h24447 ^ wdata[14] ; + assign z__h24461 = z__h24454 ^ wdata[15] ; + assign z__h24468 = z__h24461 ^ wdata[0] ; + assign z__h24475 = z__h24468 ^ wdata[1] ; + assign z__h24482 = z__h24475 ^ wdata[2] ; + assign z__h24489 = z__h24482 ^ wdata[3] ; + assign z__h24496 = z__h24489 ^ wdata[4] ; + assign z__h24503 = z__h24496 ^ wdata[5] ; + assign z__h24510 = z__h24503 ^ wdata[6] ; + assign z__h34868 = swd_controller_data[0] ^ swd_controller_data[1] ; + assign z__h34875 = z__h34868 ^ swd_controller_data[2] ; + assign z__h34882 = z__h34875 ^ swd_controller_data[3] ; + assign z__h34889 = z__h34882 ^ swd_controller_data[4] ; + assign z__h34896 = z__h34889 ^ swd_controller_data[5] ; + assign z__h34903 = z__h34896 ^ swd_controller_data[6] ; + assign z__h34910 = z__h34903 ^ swd_controller_data[7] ; + assign z__h34917 = z__h34910 ^ swd_controller_data[8] ; + assign z__h34924 = z__h34917 ^ swd_controller_data[9] ; + assign z__h34931 = z__h34924 ^ swd_controller_data[10] ; + assign z__h34938 = z__h34931 ^ swd_controller_data[11] ; + assign z__h34945 = z__h34938 ^ swd_controller_data[12] ; + assign z__h34952 = z__h34945 ^ swd_controller_data[13] ; + assign z__h34959 = z__h34952 ^ swd_controller_data[14] ; + assign z__h34966 = z__h34959 ^ swd_controller_data[15] ; + assign z__h34973 = z__h34966 ^ swd_controller_data[16] ; + assign z__h34980 = z__h34973 ^ swd_controller_data[17] ; + assign z__h34987 = z__h34980 ^ swd_controller_data[18] ; + assign z__h34994 = z__h34987 ^ swd_controller_data[19] ; + assign z__h35001 = z__h34994 ^ swd_controller_data[20] ; + assign z__h35008 = z__h35001 ^ swd_controller_data[21] ; + assign z__h35015 = z__h35008 ^ swd_controller_data[22] ; + assign z__h35022 = z__h35015 ^ swd_controller_data[23] ; + assign z__h35029 = z__h35022 ^ swd_controller_data[24] ; + assign z__h35036 = z__h35029 ^ swd_controller_data[25] ; + assign z__h35043 = z__h35036 ^ swd_controller_data[26] ; + assign z__h35050 = z__h35043 ^ swd_controller_data[27] ; + assign z__h35057 = z__h35050 ^ swd_controller_data[28] ; + assign z__h35064 = z__h35057 ^ swd_controller_data[29] ; + assign z__h35071 = z__h35064 ^ swd_controller_data[30] ; + assign z__h35078 = z__h35071 ^ swd_controller_data[31] ; // handling of inlined registers From 0c999f29fbb49b0cab6ae40b64693ca69e325df8 Mon Sep 17 00:00:00 2001 From: cchr Date: Thu, 5 Sep 2024 16:36:40 +0200 Subject: [PATCH 21/24] Add trigger output --- api/scaffold/__init__.py | 12 +- fpga-arch/bsv/SWD.bsv | 12 +- fpga-arch/bsv/SWDInner.bsv | 2 +- fpga-arch/swd_module.v | 318 +++++++++++++++++++------------------ fpga-arch/system.vhd | 19 ++- 5 files changed, 199 insertions(+), 164 deletions(-) diff --git a/api/scaffold/__init__.py b/api/scaffold/__init__.py index 509f650..dffaa5e 100644 --- a/api/scaffold/__init__.py +++ b/api/scaffold/__init__.py @@ -1625,7 +1625,7 @@ def __init__(self, parent): """ super().__init__(parent, "/swd") # Declare the signals - self.add_signals("swclk", "swd_in", "swd_out") + self.add_signals("swclk", "swd_in", "swd_out", "trigger") # Declare the registers self.__addr_base = base = 0x0b00 self.add_register("rdata", "rv", base) @@ -1633,13 +1633,16 @@ def __init__(self, parent): self.add_register("status", "rv", base + 0x10) self.add_register("cmd", "w", base + 0x20) - def reset(self): + def reset(self, trigger=False): """ Reset the debug interface. This emits a reset sequence, followed by the JTAG-to-SWD select sequence and a second reset sequence. The deviceid register is then read. """ - self.reg_cmd.write(0x80) + val = 0x80 + if trigger: + val = val | (1 << 6) + self.reg_cmd.write(val) self.read(0, 0) return self.status() @@ -2340,6 +2343,8 @@ def connect( self.add_mtxl_in(f"/pgen{i}/out") for i in range(len(self.chains)): self.add_mtxl_in(f"/chain{i}/trigger") + if self.version >= parse_version("0.10"): + self.add_mtxl_in(f"/swd/trigger") # FPGA left matrix output signals # Update this section when adding new modules with inputs @@ -2397,6 +2402,7 @@ def connect( if self.version >= parse_version("0.10"): self.add_mtxr_in("/swd/swclk") self.add_mtxr_in("/swd/swd_out") + self.add_mtxr_in("/swd/trigger") # FPGA right matrix output signals self.add_mtxr_out("/io/a0") diff --git a/fpga-arch/bsv/SWD.bsv b/fpga-arch/bsv/SWD.bsv index 928b2b6..4f63e4b 100644 --- a/fpga-arch/bsv/SWD.bsv +++ b/fpga-arch/bsv/SWD.bsv @@ -45,11 +45,13 @@ endinterface interface ScaffoldSWDModule; (* prefix="" *) interface ScaffoldBus bus; (* prefix="" *) interface SWDControllerPins pins; + (* always_ready, prefix="" *) method Bit#(1) trigger; endinterface typedef struct { Bit#(1) reset; - Bit#(3) reserved; + Bit#(1) trigger; + Bit#(2) reserved; Bit#(1) apndp; Bit#(1) rnw; Bit#(2) addr; @@ -77,6 +79,8 @@ module swd_module (ScaffoldSWDModule); Reg#(Bit#(8)) bus_reg_rdata <- mkRegA(0); Reg#(Bit#(8)) bus_reg_status <- mkRegA(0); + PulseWire trig <- mkPulseWire(); + Reg#(Vector#(4, Bit#(8))) rdata <- mkRegA(unpack(0)); Reg#(Status) status <- mkRegA(unpack(0)); Reg#(Vector#(4, Bit#(8))) wdata <- mkRegA(unpack(0)); @@ -131,6 +135,10 @@ module swd_module (ScaffoldSWDModule); ); state <= RW; end + + if (new_cmd.trigger == 1) begin + trig.send(); + end endrule rule do_reset (state == RESET); @@ -184,4 +192,6 @@ module swd_module (ScaffoldSWDModule); endinterface interface SWDControllerPins pins = swd_controller.pins; + + method Bit#(1) trigger = pack(trig); endmodule \ No newline at end of file diff --git a/fpga-arch/bsv/SWDInner.bsv b/fpga-arch/bsv/SWDInner.bsv index dfa5bf3..7ac0d6d 100644 --- a/fpga-arch/bsv/SWDInner.bsv +++ b/fpga-arch/bsv/SWDInner.bsv @@ -157,7 +157,7 @@ module mkSWDController (SWDController#(clk_divider)) PulseWire reset_in <- mkPulseWire(); rule do_prescaler; - if (request_in) begin + if (request_in || reset_in) begin prescaler.reset(); end endrule diff --git a/fpga-arch/swd_module.v b/fpga-arch/swd_module.v index 07d8408..90ae02e 100644 --- a/fpga-arch/swd_module.v +++ b/fpga-arch/swd_module.v @@ -1,7 +1,7 @@ // // Generated by Bluespec Compiler, version 2024.01-9-gc481d7f5 (build c481d7f5) // -// On Wed Sep 4 10:01:30 CEST 2024 +// On Thu Sep 5 16:29:16 CEST 2024 // // // Ports: @@ -11,6 +11,7 @@ // swclk O 1 reg // swd_out O 1 reg // out_en O 1 reg +// trigger O 1 // CLK I 1 clock // RST_N I 1 reset // address I 16 unused @@ -23,7 +24,8 @@ // en_status I 1 // swd_in I 1 // -// No combinational paths from inputs to outputs +// Combinational paths from inputs to outputs: +// write -> trigger // // @@ -69,7 +71,9 @@ module swd_module(CLK, swd_out, - out_en); + out_en, + + trigger); input CLK; input RST_N; @@ -115,9 +119,12 @@ module swd_module(CLK, // value method pins_out_en output out_en; + // value method trigger + output trigger; + // signals for module outputs wire [7 : 0] reg_rdata, reg_status; - wire out_en, swclk, swd_out; + wire out_en, swclk, swd_out, trigger; // inlined wires wire swd_controller_request_in$whas, swd_controller_reset_in$whas; @@ -275,77 +282,77 @@ module swd_module(CLK, // remaining internal signals wire [15 : 0] _0xE79E__q2; - wire [6 : 0] i__h1364, x__h14824; + wire [6 : 0] i__h1365, x__h14825; wire [1 : 0] cmd_BITS_1_TO_0__q1; wire swd_controller_cnt_2_ULE_8___d35, - swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d300, - x__h1345, - x__h19907, - x__h19920, - x__h19922, - x__h21060, - x__h21073, - z__h24307, - z__h24314, - z__h24321, - z__h24328, - z__h24335, - z__h24342, - z__h24349, - z__h24356, - z__h24363, - z__h24370, - z__h24377, - z__h24384, - z__h24391, - z__h24398, - z__h24405, - z__h24412, - z__h24419, - z__h24426, - z__h24433, - z__h24440, - z__h24447, - z__h24454, - z__h24461, - z__h24468, - z__h24475, - z__h24482, - z__h24489, - z__h24496, - z__h24503, - z__h24510, - z__h34868, - z__h34875, - z__h34882, - z__h34889, - z__h34896, - z__h34903, - z__h34910, - z__h34917, - z__h34924, - z__h34931, - z__h34938, - z__h34945, - z__h34952, - z__h34959, - z__h34966, - z__h34973, - z__h34980, - z__h34987, - z__h34994, - z__h35001, - z__h35008, - z__h35015, - z__h35022, - z__h35029, - z__h35036, - z__h35043, - z__h35050, - z__h35057, - z__h35064, - z__h35071, - z__h35078; + swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d301, + x__h1346, + x__h20049, + x__h20062, + x__h20064, + x__h21248, + x__h21261, + z__h24495, + z__h24502, + z__h24509, + z__h24516, + z__h24523, + z__h24530, + z__h24537, + z__h24544, + z__h24551, + z__h24558, + z__h24565, + z__h24572, + z__h24579, + z__h24586, + z__h24593, + z__h24600, + z__h24607, + z__h24614, + z__h24621, + z__h24628, + z__h24635, + z__h24642, + z__h24649, + z__h24656, + z__h24663, + z__h24670, + z__h24677, + z__h24684, + z__h24691, + z__h24698, + z__h35143, + z__h35150, + z__h35157, + z__h35164, + z__h35171, + z__h35178, + z__h35185, + z__h35192, + z__h35199, + z__h35206, + z__h35213, + z__h35220, + z__h35227, + z__h35234, + z__h35241, + z__h35248, + z__h35255, + z__h35262, + z__h35269, + z__h35276, + z__h35283, + z__h35290, + z__h35297, + z__h35304, + z__h35311, + z__h35318, + z__h35325, + z__h35332, + z__h35339, + z__h35346, + z__h35353; // value method bus_reg_rdata assign reg_rdata = bus_reg_rdata ; @@ -362,6 +369,9 @@ module swd_module(CLK, // value method pins_out_en assign out_en = swd_controller_out_en ; + // value method trigger + assign trigger = WILL_FIRE_RL_do_idle && cmd[6] ; + // submodule swd_controller_prescaler_ctr Counter #(.width(32'd8), .init(8'd99)) swd_controller_prescaler_ctr(.CLK(CLK), @@ -489,7 +499,7 @@ module swd_module(CLK, assign MUX_rdata$write_1__VAL_1 = { 8'd0, rdata[31:8] } ; assign MUX_rdata$write_1__VAL_2 = swd_controller_rnw ? - (swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d300 ? + (swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d301 ? 32'd0 : swd_controller_data[31:0]) : 32'd0 ; @@ -500,22 +510,22 @@ module swd_module(CLK, swd_controller_request_in$whas ? 7'd10 : 7'd126 ; assign MUX_swd_controller_cnt$write_1__VAL_5 = (swd_controller_prescaler_ctr$Q_OUT == 8'd0) ? - x__h14824 : + x__h14825 : 7'd33 ; assign MUX_swd_controller_cnt$write_1__VAL_6 = - (swd_controller_prescaler_ctr$Q_OUT == 8'd0) ? x__h14824 : 7'd1 ; + (swd_controller_prescaler_ctr$Q_OUT == 8'd0) ? x__h14825 : 7'd1 ; assign MUX_swd_controller_data$write_1__VAL_1 = { swd_in, swd_controller_data[32:1] } ; assign MUX_swd_controller_data$write_1__VAL_2 = { 1'd0, swd_controller_data[32:1] } ; assign MUX_swd_controller_data$write_1__VAL_3 = - { z__h24510 ^ wdata[7], + { z__h24698 ^ wdata[7], wdata[7:0], wdata[15:8], wdata[23:16], wdata[31:24] } ; assign MUX_swd_controller_packet$write_1__VAL_2 = - { 1'd1, cmd[3:0], cmd[2] ? x__h19907 : x__h21060, 2'd1 } ; + { 1'd1, cmd[3:0], cmd[2] ? x__h20049 : x__h21248, 2'd1 } ; assign MUX_swd_controller_packet$write_1__VAL_3 = { swd_controller_packet[6:0], 1'd0 } ; assign MUX_swd_controller_state$write_1__VAL_1 = @@ -535,7 +545,7 @@ module swd_module(CLK, end assign MUX_swd_controller_swd_out$write_1__VAL_2 = swd_controller_cnt > 7'd71 || swd_controller_cnt <= 7'd55 || - x__h1345 ; + x__h1346 ; assign MUX_swd_controller_swd_out$write_1__VAL_3 = swd_controller_cnt_2_ULE_8___d35 && swd_controller_packet[7] ; @@ -587,7 +597,7 @@ module swd_module(CLK, // register status assign status$D_IN = swd_controller_rnw ? - (swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d300 ? + (swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d301 ? 2'd3 : swd_controller_status[1:0]) : swd_controller_status[1:0] ; @@ -601,7 +611,7 @@ module swd_module(CLK, // register swd_controller_cnt always@(MUX_swd_controller_cnt$write_1__SEL_1 or - x__h14824 or + x__h14825 or MUX_swd_controller_cnt$write_1__SEL_2 or MUX_swd_controller_cnt$write_1__VAL_2 or MUX_swd_controller_cnt$write_1__SEL_3 or @@ -614,7 +624,7 @@ module swd_module(CLK, begin case (1'b1) // synopsys parallel_case MUX_swd_controller_cnt$write_1__SEL_1: - swd_controller_cnt$D_IN = x__h14824; + swd_controller_cnt$D_IN = x__h14825; MUX_swd_controller_cnt$write_1__SEL_2: swd_controller_cnt$D_IN = MUX_swd_controller_cnt$write_1__VAL_2; MUX_swd_controller_cnt$write_1__SEL_3: swd_controller_cnt$D_IN = 7'd3; @@ -835,84 +845,84 @@ module swd_module(CLK, swd_controller_prescaler_ctr$Q_OUT != 8'd0 ; assign swd_controller_prescaler_ctr$SETC = 1'b0 ; assign swd_controller_prescaler_ctr$SETF = - swd_controller_request_in$whas || + swd_controller_request_in$whas || swd_controller_reset_in$whas || swd_controller_prescaler_ctr$Q_OUT == 8'd0 ; // remaining internal signals assign _0xE79E__q2 = 16'hE79E ; assign cmd_BITS_1_TO_0__q1 = cmd[1:0] ; - assign i__h1364 = 7'd71 - swd_controller_cnt ; + assign i__h1365 = 7'd71 - swd_controller_cnt ; assign swd_controller_cnt_2_ULE_8___d35 = swd_controller_cnt <= 7'd8 ; - assign swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d300 = - z__h35078 ^ swd_controller_data[32] ; - assign x__h1345 = _0xE79E__q2[i__h1364[3:0]] ; - assign x__h14824 = swd_controller_cnt - 7'd1 ; - assign x__h19907 = x__h19920 ^ cmd_BITS_1_TO_0__q1[1] ; - assign x__h19920 = x__h19922 ^ cmd_BITS_1_TO_0__q1[0] ; - assign x__h19922 = ~cmd[3] ; - assign x__h21060 = x__h21073 ^ cmd_BITS_1_TO_0__q1[1] ; - assign x__h21073 = cmd[3] ^ cmd_BITS_1_TO_0__q1[0] ; - assign z__h24307 = wdata[24] ^ wdata[25] ; - assign z__h24314 = z__h24307 ^ wdata[26] ; - assign z__h24321 = z__h24314 ^ wdata[27] ; - assign z__h24328 = z__h24321 ^ wdata[28] ; - assign z__h24335 = z__h24328 ^ wdata[29] ; - assign z__h24342 = z__h24335 ^ wdata[30] ; - assign z__h24349 = z__h24342 ^ wdata[31] ; - assign z__h24356 = z__h24349 ^ wdata[16] ; - assign z__h24363 = z__h24356 ^ wdata[17] ; - assign z__h24370 = z__h24363 ^ wdata[18] ; - assign z__h24377 = z__h24370 ^ wdata[19] ; - assign z__h24384 = z__h24377 ^ wdata[20] ; - assign z__h24391 = z__h24384 ^ wdata[21] ; - assign z__h24398 = z__h24391 ^ wdata[22] ; - assign z__h24405 = z__h24398 ^ wdata[23] ; - assign z__h24412 = z__h24405 ^ wdata[8] ; - assign z__h24419 = z__h24412 ^ wdata[9] ; - assign z__h24426 = z__h24419 ^ wdata[10] ; - assign z__h24433 = z__h24426 ^ wdata[11] ; - assign z__h24440 = z__h24433 ^ wdata[12] ; - assign z__h24447 = z__h24440 ^ wdata[13] ; - assign z__h24454 = z__h24447 ^ wdata[14] ; - assign z__h24461 = z__h24454 ^ wdata[15] ; - assign z__h24468 = z__h24461 ^ wdata[0] ; - assign z__h24475 = z__h24468 ^ wdata[1] ; - assign z__h24482 = z__h24475 ^ wdata[2] ; - assign z__h24489 = z__h24482 ^ wdata[3] ; - assign z__h24496 = z__h24489 ^ wdata[4] ; - assign z__h24503 = z__h24496 ^ wdata[5] ; - assign z__h24510 = z__h24503 ^ wdata[6] ; - assign z__h34868 = swd_controller_data[0] ^ swd_controller_data[1] ; - assign z__h34875 = z__h34868 ^ swd_controller_data[2] ; - assign z__h34882 = z__h34875 ^ swd_controller_data[3] ; - assign z__h34889 = z__h34882 ^ swd_controller_data[4] ; - assign z__h34896 = z__h34889 ^ swd_controller_data[5] ; - assign z__h34903 = z__h34896 ^ swd_controller_data[6] ; - assign z__h34910 = z__h34903 ^ swd_controller_data[7] ; - assign z__h34917 = z__h34910 ^ swd_controller_data[8] ; - assign z__h34924 = z__h34917 ^ swd_controller_data[9] ; - assign z__h34931 = z__h34924 ^ swd_controller_data[10] ; - assign z__h34938 = z__h34931 ^ swd_controller_data[11] ; - assign z__h34945 = z__h34938 ^ swd_controller_data[12] ; - assign z__h34952 = z__h34945 ^ swd_controller_data[13] ; - assign z__h34959 = z__h34952 ^ swd_controller_data[14] ; - assign z__h34966 = z__h34959 ^ swd_controller_data[15] ; - assign z__h34973 = z__h34966 ^ swd_controller_data[16] ; - assign z__h34980 = z__h34973 ^ swd_controller_data[17] ; - assign z__h34987 = z__h34980 ^ swd_controller_data[18] ; - assign z__h34994 = z__h34987 ^ swd_controller_data[19] ; - assign z__h35001 = z__h34994 ^ swd_controller_data[20] ; - assign z__h35008 = z__h35001 ^ swd_controller_data[21] ; - assign z__h35015 = z__h35008 ^ swd_controller_data[22] ; - assign z__h35022 = z__h35015 ^ swd_controller_data[23] ; - assign z__h35029 = z__h35022 ^ swd_controller_data[24] ; - assign z__h35036 = z__h35029 ^ swd_controller_data[25] ; - assign z__h35043 = z__h35036 ^ swd_controller_data[26] ; - assign z__h35050 = z__h35043 ^ swd_controller_data[27] ; - assign z__h35057 = z__h35050 ^ swd_controller_data[28] ; - assign z__h35064 = z__h35057 ^ swd_controller_data[29] ; - assign z__h35071 = z__h35064 ^ swd_controller_data[30] ; - assign z__h35078 = z__h35071 ^ swd_controller_data[31] ; + assign swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d301 = + z__h35353 ^ swd_controller_data[32] ; + assign x__h1346 = _0xE79E__q2[i__h1365[3:0]] ; + assign x__h14825 = swd_controller_cnt - 7'd1 ; + assign x__h20049 = x__h20062 ^ cmd_BITS_1_TO_0__q1[1] ; + assign x__h20062 = x__h20064 ^ cmd_BITS_1_TO_0__q1[0] ; + assign x__h20064 = ~cmd[3] ; + assign x__h21248 = x__h21261 ^ cmd_BITS_1_TO_0__q1[1] ; + assign x__h21261 = cmd[3] ^ cmd_BITS_1_TO_0__q1[0] ; + assign z__h24495 = wdata[24] ^ wdata[25] ; + assign z__h24502 = z__h24495 ^ wdata[26] ; + assign z__h24509 = z__h24502 ^ wdata[27] ; + assign z__h24516 = z__h24509 ^ wdata[28] ; + assign z__h24523 = z__h24516 ^ wdata[29] ; + assign z__h24530 = z__h24523 ^ wdata[30] ; + assign z__h24537 = z__h24530 ^ wdata[31] ; + assign z__h24544 = z__h24537 ^ wdata[16] ; + assign z__h24551 = z__h24544 ^ wdata[17] ; + assign z__h24558 = z__h24551 ^ wdata[18] ; + assign z__h24565 = z__h24558 ^ wdata[19] ; + assign z__h24572 = z__h24565 ^ wdata[20] ; + assign z__h24579 = z__h24572 ^ wdata[21] ; + assign z__h24586 = z__h24579 ^ wdata[22] ; + assign z__h24593 = z__h24586 ^ wdata[23] ; + assign z__h24600 = z__h24593 ^ wdata[8] ; + assign z__h24607 = z__h24600 ^ wdata[9] ; + assign z__h24614 = z__h24607 ^ wdata[10] ; + assign z__h24621 = z__h24614 ^ wdata[11] ; + assign z__h24628 = z__h24621 ^ wdata[12] ; + assign z__h24635 = z__h24628 ^ wdata[13] ; + assign z__h24642 = z__h24635 ^ wdata[14] ; + assign z__h24649 = z__h24642 ^ wdata[15] ; + assign z__h24656 = z__h24649 ^ wdata[0] ; + assign z__h24663 = z__h24656 ^ wdata[1] ; + assign z__h24670 = z__h24663 ^ wdata[2] ; + assign z__h24677 = z__h24670 ^ wdata[3] ; + assign z__h24684 = z__h24677 ^ wdata[4] ; + assign z__h24691 = z__h24684 ^ wdata[5] ; + assign z__h24698 = z__h24691 ^ wdata[6] ; + assign z__h35143 = swd_controller_data[0] ^ swd_controller_data[1] ; + assign z__h35150 = z__h35143 ^ swd_controller_data[2] ; + assign z__h35157 = z__h35150 ^ swd_controller_data[3] ; + assign z__h35164 = z__h35157 ^ swd_controller_data[4] ; + assign z__h35171 = z__h35164 ^ swd_controller_data[5] ; + assign z__h35178 = z__h35171 ^ swd_controller_data[6] ; + assign z__h35185 = z__h35178 ^ swd_controller_data[7] ; + assign z__h35192 = z__h35185 ^ swd_controller_data[8] ; + assign z__h35199 = z__h35192 ^ swd_controller_data[9] ; + assign z__h35206 = z__h35199 ^ swd_controller_data[10] ; + assign z__h35213 = z__h35206 ^ swd_controller_data[11] ; + assign z__h35220 = z__h35213 ^ swd_controller_data[12] ; + assign z__h35227 = z__h35220 ^ swd_controller_data[13] ; + assign z__h35234 = z__h35227 ^ swd_controller_data[14] ; + assign z__h35241 = z__h35234 ^ swd_controller_data[15] ; + assign z__h35248 = z__h35241 ^ swd_controller_data[16] ; + assign z__h35255 = z__h35248 ^ swd_controller_data[17] ; + assign z__h35262 = z__h35255 ^ swd_controller_data[18] ; + assign z__h35269 = z__h35262 ^ swd_controller_data[19] ; + assign z__h35276 = z__h35269 ^ swd_controller_data[20] ; + assign z__h35283 = z__h35276 ^ swd_controller_data[21] ; + assign z__h35290 = z__h35283 ^ swd_controller_data[22] ; + assign z__h35297 = z__h35290 ^ swd_controller_data[23] ; + assign z__h35304 = z__h35297 ^ swd_controller_data[24] ; + assign z__h35311 = z__h35304 ^ swd_controller_data[25] ; + assign z__h35318 = z__h35311 ^ swd_controller_data[26] ; + assign z__h35325 = z__h35318 ^ swd_controller_data[27] ; + assign z__h35332 = z__h35325 ^ swd_controller_data[28] ; + assign z__h35339 = z__h35332 ^ swd_controller_data[29] ; + assign z__h35346 = z__h35339 ^ swd_controller_data[30] ; + assign z__h35353 = z__h35346 ^ swd_controller_data[31] ; // handling of inlined registers diff --git a/fpga-arch/system.vhd b/fpga-arch/system.vhd index 4e8cb51..0d851fd 100644 --- a/fpga-arch/system.vhd +++ b/fpga-arch/system.vhd @@ -128,7 +128,8 @@ architecture behavior of system is swclk : OUT STD_LOGIC; swd_in : IN STD_LOGIC; swd_out : OUT STD_LOGIC; - out_en : OUT STD_LOGIC + out_en : OUT STD_LOGIC; + trigger : OUT STD_LOGIC ); END COMPONENT; @@ -174,6 +175,7 @@ architecture behavior of system is + 1 -- ISO7816 trigger + 1 -- I2C trigger + 1 -- SPI trigger + + 1 -- SWD trigger + pulse_gen_count -- Pulse generator outputs + chain_count; -- Chain trigger signal mtxl_in: std_logic_vector(mtxl_in_count-1 downto 0); @@ -211,7 +213,7 @@ architecture behavior of system is + 4 -- SPI module + 1 -- SPI slave module + 1 -- Clock - + 2; -- SWD + + 3; -- SWD signal mtxr_in: tristate_array_t(mtxr_in_count-1 downto 0); signal mtxr_in_uart_tx: std_logic_vector(uart_count-1 downto 0); signal mtxr_in_uart_trigger: std_logic_vector(uart_count-1 downto 0); @@ -233,6 +235,7 @@ architecture behavior of system is signal mtxr_in_swd_swdio: std_logic; signal mtxr_in_swd_swdio_en: std_logic; signal mtxr_in_swd_swclk: std_logic; + signal mtxr_in_swd_trigger: std_logic; signal mtxr_in_chain_out: std_logic_vector(chain_count-1 downto 0); -- Output signals of the output matrix @@ -742,6 +745,7 @@ begin output => mtxr_in_clock_out, glitch_start => mtxl_out_clock_glitch_start ); + -- SWD module c_swd: component swd_module port map ( CLK => clock, @@ -759,7 +763,8 @@ begin swclk => mtxr_in_swd_swclk, swd_in => mtxl_out_swd_swdio, swd_out => mtxr_in_swd_swdio, - out_en => mtxr_in_swd_swdio_en ); + out_en => mtxr_in_swd_swdio_en, + trigger => mtxr_in_swd_trigger ); -- Left matrix module e_left_matrix_module: entity work.left_matrix_module @@ -809,6 +814,7 @@ begin -- mtxr signals are feedback outputs of modules. -- Warning: signals order is inversed regarding Python API code. mtxl_in <= + mtxr_in_swd_trigger & mtxr_in_chain_out & mtxr_in_pulse_gen_out & mtxr_in_spi_trigger & @@ -855,7 +861,8 @@ begin mtxr_in_clock_out, mtxr_in_swd_swclk, mtxr_in_swd_swdio, - mtxr_in_swd_swdio_en + mtxr_in_swd_swdio_en, + mtxr_in_swd_trigger ) variable i: integer; begin @@ -904,9 +911,11 @@ begin -- Clock module mtxr_in(i) <= "1" & mtxr_in_clock_out; i := i + 1; + -- SWD module mtxr_in(i) <= "1" & mtxr_in_swd_swclk; mtxr_in(i+1) <= mtxr_in_swd_swdio_en & mtxr_in_swd_swdio; - i := i + 2; + mtxr_in(i+2) <= "1" & mtxr_in_swd_trigger; + i := i + 3; -- If you add other signals, please dont forget to update the sensivity -- list for simulation support. assert i = mtxr_in_count; From 7ad9d2b9077714fc110306e4013dc16119e6149e Mon Sep 17 00:00:00 2001 From: cchr Date: Thu, 5 Sep 2024 16:41:33 +0200 Subject: [PATCH 22/24] Satisfy linter --- api/scaffold/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/scaffold/__init__.py b/api/scaffold/__init__.py index dffaa5e..9df200d 100644 --- a/api/scaffold/__init__.py +++ b/api/scaffold/__init__.py @@ -2344,7 +2344,7 @@ def connect( for i in range(len(self.chains)): self.add_mtxl_in(f"/chain{i}/trigger") if self.version >= parse_version("0.10"): - self.add_mtxl_in(f"/swd/trigger") + self.add_mtxl_in("/swd/trigger") # FPGA left matrix output signals # Update this section when adding new modules with inputs From b71173fa0ecd53f3bb9c1bd4ee6da533a555eaab Mon Sep 17 00:00:00 2001 From: cchr Date: Mon, 9 Sep 2024 11:09:41 +0200 Subject: [PATCH 23/24] Take review comments into account --- fpga-arch/bsv/SWD.bsv | 1 - fpga-arch/bsv/SWDInner.bsv | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/fpga-arch/bsv/SWD.bsv b/fpga-arch/bsv/SWD.bsv index 4f63e4b..3063910 100644 --- a/fpga-arch/bsv/SWD.bsv +++ b/fpga-arch/bsv/SWD.bsv @@ -20,7 +20,6 @@ import SWDInner::*; import GetPut::*; import Vector::*; -import StmtFSM::*; import ClientServer::*; (* always_enabled *) diff --git a/fpga-arch/bsv/SWDInner.bsv b/fpga-arch/bsv/SWDInner.bsv index 7ac0d6d..650c701 100644 --- a/fpga-arch/bsv/SWDInner.bsv +++ b/fpga-arch/bsv/SWDInner.bsv @@ -20,7 +20,6 @@ package SWDInner; import Prescaler::*; -import StmtFSM::*; import GetPut::*; import Vector::*; import ClientServer::*; @@ -222,7 +221,7 @@ module mkSWDController (SWDController#(clk_divider)) end end - else if (prescaler.pre_rising && (cnt == 0)) begin + if (prescaler.pre_rising && (cnt == 0)) begin state <= IDLE; end endrule From f61de5007b2ad494d322c68804eee646928b8521 Mon Sep 17 00:00:00 2001 From: cchr Date: Mon, 9 Sep 2024 13:21:06 +0200 Subject: [PATCH 24/24] Introduce separate CMD_IN state --- fpga-arch/bsv/SWD.bsv | 7 +- fpga-arch/swd_module.v | 350 +++++++++++++++++++++-------------------- 2 files changed, 180 insertions(+), 177 deletions(-) diff --git a/fpga-arch/bsv/SWD.bsv b/fpga-arch/bsv/SWD.bsv index 3063910..bdcb5c8 100644 --- a/fpga-arch/bsv/SWD.bsv +++ b/fpga-arch/bsv/SWD.bsv @@ -58,6 +58,7 @@ typedef struct { typedef enum { IDLE, + CMD_IN, RESET, RW } State deriving (Eq, Bits); @@ -97,6 +98,7 @@ module swd_module (ScaffoldSWDModule); bus_reg_status <= {pack(state == IDLE), 5'b0, pack(status)}; endrule + // Only register writes if we are currently idling rule do_bus_write ((bus_write == 1) && (state == IDLE)); if (bus_en_wdata == 1) begin wdata <= shiftInAt0(wdata, bus_write_data); @@ -104,6 +106,7 @@ module swd_module (ScaffoldSWDModule); if (bus_en_cmd == 1) begin cmd <= tagged Valid(unpack(bus_write_data)); + state <= CMD_IN; end endrule @@ -111,9 +114,7 @@ module swd_module (ScaffoldSWDModule); ready <= swd_controller.ready; endrule - // ONLY do something if there is a valid command registered, and if - // the user is not currently writing to some register. - rule do_idle ((state == IDLE) && (bus_write == 0) && isValid(cmd)); + rule do_cmd ((state == CMD_IN) && isValid(cmd)); let new_cmd = fromMaybe(?, cmd); if (new_cmd.reset == 1) begin diff --git a/fpga-arch/swd_module.v b/fpga-arch/swd_module.v index 90ae02e..f6512cb 100644 --- a/fpga-arch/swd_module.v +++ b/fpga-arch/swd_module.v @@ -1,7 +1,7 @@ // // Generated by Bluespec Compiler, version 2024.01-9-gc481d7f5 (build c481d7f5) // -// On Thu Sep 5 16:29:16 CEST 2024 +// On Mon Sep 9 13:18:32 CEST 2024 // // // Ports: @@ -24,8 +24,7 @@ // en_status I 1 // swd_in I 1 // -// Combinational paths from inputs to outputs: -// write -> trigger +// No combinational paths from inputs to outputs // // @@ -229,7 +228,7 @@ module swd_module(CLK, // rule scheduling signals wire WILL_FIRE_RL_do_bus_read_rdata, WILL_FIRE_RL_do_bus_write, - WILL_FIRE_RL_do_idle, + WILL_FIRE_RL_do_cmd, WILL_FIRE_RL_do_reset, WILL_FIRE_RL_do_rw; @@ -249,7 +248,7 @@ module swd_module(CLK, wire [3 : 0] MUX_swd_controller_state$write_1__VAL_1, MUX_swd_controller_state$write_1__VAL_3, MUX_swd_controller_state$write_1__VAL_7; - wire [1 : 0] MUX_state$write_1__VAL_2; + wire [1 : 0] MUX_state$write_1__VAL_3; wire MUX_cmd$write_1__SEL_1, MUX_state$write_1__SEL_1, MUX_swd_controller_cnt$write_1__PSEL_1, @@ -282,77 +281,77 @@ module swd_module(CLK, // remaining internal signals wire [15 : 0] _0xE79E__q2; - wire [6 : 0] i__h1365, x__h14825; + wire [6 : 0] i__h1457, x__h15006; wire [1 : 0] cmd_BITS_1_TO_0__q1; wire swd_controller_cnt_2_ULE_8___d35, - swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d301, - x__h1346, - x__h20049, - x__h20062, - x__h20064, - x__h21248, - x__h21261, - z__h24495, - z__h24502, - z__h24509, - z__h24516, - z__h24523, - z__h24530, - z__h24537, - z__h24544, - z__h24551, - z__h24558, - z__h24565, - z__h24572, - z__h24579, - z__h24586, - z__h24593, - z__h24600, - z__h24607, - z__h24614, - z__h24621, - z__h24628, - z__h24635, - z__h24642, - z__h24649, - z__h24656, - z__h24663, - z__h24670, - z__h24677, - z__h24684, - z__h24691, - z__h24698, - z__h35143, - z__h35150, - z__h35157, - z__h35164, - z__h35171, - z__h35178, - z__h35185, - z__h35192, - z__h35199, - z__h35206, - z__h35213, - z__h35220, - z__h35227, - z__h35234, - z__h35241, - z__h35248, - z__h35255, - z__h35262, - z__h35269, - z__h35276, - z__h35283, - z__h35290, - z__h35297, - z__h35304, - z__h35311, - z__h35318, - z__h35325, - z__h35332, - z__h35339, - z__h35346, - z__h35353; + swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d298, + x__h1438, + x__h20247, + x__h20260, + x__h20262, + x__h21446, + x__h21459, + z__h24693, + z__h24700, + z__h24707, + z__h24714, + z__h24721, + z__h24728, + z__h24735, + z__h24742, + z__h24749, + z__h24756, + z__h24763, + z__h24770, + z__h24777, + z__h24784, + z__h24791, + z__h24798, + z__h24805, + z__h24812, + z__h24819, + z__h24826, + z__h24833, + z__h24840, + z__h24847, + z__h24854, + z__h24861, + z__h24868, + z__h24875, + z__h24882, + z__h24889, + z__h24896, + z__h35341, + z__h35348, + z__h35355, + z__h35362, + z__h35369, + z__h35376, + z__h35383, + z__h35390, + z__h35397, + z__h35404, + z__h35411, + z__h35418, + z__h35425, + z__h35432, + z__h35439, + z__h35446, + z__h35453, + z__h35460, + z__h35467, + z__h35474, + z__h35481, + z__h35488, + z__h35495, + z__h35502, + z__h35509, + z__h35516, + z__h35523, + z__h35530, + z__h35537, + z__h35544, + z__h35551; // value method bus_reg_rdata assign reg_rdata = bus_reg_rdata ; @@ -370,7 +369,7 @@ module swd_module(CLK, assign out_en = swd_controller_out_en ; // value method trigger - assign trigger = WILL_FIRE_RL_do_idle && cmd[6] ; + assign trigger = WILL_FIRE_RL_do_cmd && cmd[6] ; // submodule swd_controller_prescaler_ctr Counter #(.width(32'd8), @@ -387,27 +386,26 @@ module swd_module(CLK, .Q_OUT(swd_controller_prescaler_ctr$Q_OUT)); // rule RL_do_bus_read_rdata - assign WILL_FIRE_RL_do_bus_read_rdata = read && en_rdata && state != 2'd2 ; + assign WILL_FIRE_RL_do_bus_read_rdata = read && en_rdata && state != 2'd3 ; // rule RL_do_bus_write assign WILL_FIRE_RL_do_bus_write = write && state == 2'd0 ; - // rule RL_do_idle - assign WILL_FIRE_RL_do_idle = + // rule RL_do_cmd + assign WILL_FIRE_RL_do_cmd = swd_controller_state == 4'd0 && !swd_controller_status[2] && - state == 2'd0 && - !write && + state == 2'd1 && cmd[8] ; // rule RL_do_reset assign WILL_FIRE_RL_do_reset = swd_controller_state == 4'd0 && !swd_controller_status[2] && - state == 2'd1 ; + state == 2'd2 ; // rule RL_do_rw assign WILL_FIRE_RL_do_rw = swd_controller_state == 4'd0 && swd_controller_status[2] && - state == 2'd2 ; + state == 2'd3 ; // inputs to muxes for submodule ports assign MUX_cmd$write_1__SEL_1 = WILL_FIRE_RL_do_bus_write && en_cmd ; @@ -448,9 +446,9 @@ module swd_module(CLK, swd_controller_state == 4'd6 && swd_controller_prescaler_ctr$Q_OUT == 8'd0 ; assign MUX_swd_controller_data$write_1__SEL_3 = - WILL_FIRE_RL_do_idle && !cmd[7] && !cmd[2] ; + WILL_FIRE_RL_do_cmd && !cmd[7] && !cmd[2] ; assign MUX_swd_controller_packet$write_1__SEL_2 = - WILL_FIRE_RL_do_idle && !cmd[7] ; + WILL_FIRE_RL_do_cmd && !cmd[7] ; assign MUX_swd_controller_packet$write_1__SEL_3 = swd_controller_state == 4'd1 && swd_controller_prescaler_ctr$Q_OUT == 8'd0 && @@ -499,33 +497,33 @@ module swd_module(CLK, assign MUX_rdata$write_1__VAL_1 = { 8'd0, rdata[31:8] } ; assign MUX_rdata$write_1__VAL_2 = swd_controller_rnw ? - (swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d301 ? + (swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d298 ? 32'd0 : swd_controller_data[31:0]) : 32'd0 ; - assign MUX_state$write_1__VAL_2 = cmd[7] ? 2'd1 : 2'd2 ; + assign MUX_state$write_1__VAL_3 = cmd[7] ? 2'd2 : 2'd3 ; assign MUX_swd_controller_cnt$write_1__VAL_2 = (swd_controller_ack == 3'b100) ? 7'd33 : 7'd1 ; assign MUX_swd_controller_cnt$write_1__VAL_4 = swd_controller_request_in$whas ? 7'd10 : 7'd126 ; assign MUX_swd_controller_cnt$write_1__VAL_5 = (swd_controller_prescaler_ctr$Q_OUT == 8'd0) ? - x__h14825 : + x__h15006 : 7'd33 ; assign MUX_swd_controller_cnt$write_1__VAL_6 = - (swd_controller_prescaler_ctr$Q_OUT == 8'd0) ? x__h14825 : 7'd1 ; + (swd_controller_prescaler_ctr$Q_OUT == 8'd0) ? x__h15006 : 7'd1 ; assign MUX_swd_controller_data$write_1__VAL_1 = { swd_in, swd_controller_data[32:1] } ; assign MUX_swd_controller_data$write_1__VAL_2 = { 1'd0, swd_controller_data[32:1] } ; assign MUX_swd_controller_data$write_1__VAL_3 = - { z__h24698 ^ wdata[7], + { z__h24896 ^ wdata[7], wdata[7:0], wdata[15:8], wdata[23:16], wdata[31:24] } ; assign MUX_swd_controller_packet$write_1__VAL_2 = - { 1'd1, cmd[3:0], cmd[2] ? x__h20049 : x__h21248, 2'd1 } ; + { 1'd1, cmd[3:0], cmd[2] ? x__h20247 : x__h21446, 2'd1 } ; assign MUX_swd_controller_packet$write_1__VAL_3 = { swd_controller_packet[6:0], 1'd0 } ; assign MUX_swd_controller_state$write_1__VAL_1 = @@ -545,15 +543,15 @@ module swd_module(CLK, end assign MUX_swd_controller_swd_out$write_1__VAL_2 = swd_controller_cnt > 7'd71 || swd_controller_cnt <= 7'd55 || - x__h1346 ; + x__h1438 ; assign MUX_swd_controller_swd_out$write_1__VAL_3 = swd_controller_cnt_2_ULE_8___d35 && swd_controller_packet[7] ; // inlined wires assign swd_controller_request_in$whas = WILL_FIRE_RL_do_reset && ready || - WILL_FIRE_RL_do_idle && !cmd[7] ; - assign swd_controller_reset_in$whas = WILL_FIRE_RL_do_idle && cmd[7] ; + WILL_FIRE_RL_do_cmd && !cmd[7] ; + assign swd_controller_reset_in$whas = WILL_FIRE_RL_do_cmd && cmd[7] ; // register bus_reg_rdata assign bus_reg_rdata$D_IN = rdata[7:0] ; @@ -580,24 +578,28 @@ module swd_module(CLK, // register state always@(MUX_state$write_1__SEL_1 or - WILL_FIRE_RL_do_idle or - MUX_state$write_1__VAL_2 or WILL_FIRE_RL_do_rw) + MUX_cmd$write_1__SEL_1 or + WILL_FIRE_RL_do_cmd or + MUX_state$write_1__VAL_3 or WILL_FIRE_RL_do_rw) begin case (1'b1) // synopsys parallel_case - MUX_state$write_1__SEL_1: state$D_IN = 2'd2; - WILL_FIRE_RL_do_idle: state$D_IN = MUX_state$write_1__VAL_2; + MUX_state$write_1__SEL_1: state$D_IN = 2'd3; + MUX_cmd$write_1__SEL_1: state$D_IN = 2'd1; + WILL_FIRE_RL_do_cmd: state$D_IN = MUX_state$write_1__VAL_3; WILL_FIRE_RL_do_rw: state$D_IN = 2'd0; default: state$D_IN = 2'b10 /* unspecified value */ ; endcase end assign state$EN = - WILL_FIRE_RL_do_reset && ready || WILL_FIRE_RL_do_idle || + WILL_FIRE_RL_do_reset && ready || + WILL_FIRE_RL_do_bus_write && en_cmd || + WILL_FIRE_RL_do_cmd || WILL_FIRE_RL_do_rw ; // register status assign status$D_IN = swd_controller_rnw ? - (swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d301 ? + (swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d298 ? 2'd3 : swd_controller_status[1:0]) : swd_controller_status[1:0] ; @@ -611,7 +613,7 @@ module swd_module(CLK, // register swd_controller_cnt always@(MUX_swd_controller_cnt$write_1__SEL_1 or - x__h14825 or + x__h15006 or MUX_swd_controller_cnt$write_1__SEL_2 or MUX_swd_controller_cnt$write_1__VAL_2 or MUX_swd_controller_cnt$write_1__SEL_3 or @@ -624,7 +626,7 @@ module swd_module(CLK, begin case (1'b1) // synopsys parallel_case MUX_swd_controller_cnt$write_1__SEL_1: - swd_controller_cnt$D_IN = x__h14825; + swd_controller_cnt$D_IN = x__h15006; MUX_swd_controller_cnt$write_1__SEL_2: swd_controller_cnt$D_IN = MUX_swd_controller_cnt$write_1__VAL_2; MUX_swd_controller_cnt$write_1__SEL_3: swd_controller_cnt$D_IN = 7'd3; @@ -679,7 +681,7 @@ module swd_module(CLK, swd_controller_prescaler_ctr$Q_OUT == 8'd0 || swd_controller_state == 4'd6 && swd_controller_prescaler_ctr$Q_OUT == 8'd0 || - WILL_FIRE_RL_do_idle && !cmd[7] && !cmd[2] || + WILL_FIRE_RL_do_cmd && !cmd[7] && !cmd[2] || WILL_FIRE_RL_do_rw ; // register swd_controller_out_en @@ -710,7 +712,7 @@ module swd_module(CLK, end assign swd_controller_packet$EN = WILL_FIRE_RL_do_reset && ready || - WILL_FIRE_RL_do_idle && !cmd[7] || + WILL_FIRE_RL_do_cmd && !cmd[7] || swd_controller_state == 4'd1 && swd_controller_prescaler_ctr$Q_OUT == 8'd0 && swd_controller_cnt_2_ULE_8___d35 || @@ -851,78 +853,78 @@ module swd_module(CLK, // remaining internal signals assign _0xE79E__q2 = 16'hE79E ; assign cmd_BITS_1_TO_0__q1 = cmd[1:0] ; - assign i__h1365 = 7'd71 - swd_controller_cnt ; + assign i__h1457 = 7'd71 - swd_controller_cnt ; assign swd_controller_cnt_2_ULE_8___d35 = swd_controller_cnt <= 7'd8 ; - assign swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d301 = - z__h35353 ^ swd_controller_data[32] ; - assign x__h1346 = _0xE79E__q2[i__h1365[3:0]] ; - assign x__h14825 = swd_controller_cnt - 7'd1 ; - assign x__h20049 = x__h20062 ^ cmd_BITS_1_TO_0__q1[1] ; - assign x__h20062 = x__h20064 ^ cmd_BITS_1_TO_0__q1[0] ; - assign x__h20064 = ~cmd[3] ; - assign x__h21248 = x__h21261 ^ cmd_BITS_1_TO_0__q1[1] ; - assign x__h21261 = cmd[3] ^ cmd_BITS_1_TO_0__q1[0] ; - assign z__h24495 = wdata[24] ^ wdata[25] ; - assign z__h24502 = z__h24495 ^ wdata[26] ; - assign z__h24509 = z__h24502 ^ wdata[27] ; - assign z__h24516 = z__h24509 ^ wdata[28] ; - assign z__h24523 = z__h24516 ^ wdata[29] ; - assign z__h24530 = z__h24523 ^ wdata[30] ; - assign z__h24537 = z__h24530 ^ wdata[31] ; - assign z__h24544 = z__h24537 ^ wdata[16] ; - assign z__h24551 = z__h24544 ^ wdata[17] ; - assign z__h24558 = z__h24551 ^ wdata[18] ; - assign z__h24565 = z__h24558 ^ wdata[19] ; - assign z__h24572 = z__h24565 ^ wdata[20] ; - assign z__h24579 = z__h24572 ^ wdata[21] ; - assign z__h24586 = z__h24579 ^ wdata[22] ; - assign z__h24593 = z__h24586 ^ wdata[23] ; - assign z__h24600 = z__h24593 ^ wdata[8] ; - assign z__h24607 = z__h24600 ^ wdata[9] ; - assign z__h24614 = z__h24607 ^ wdata[10] ; - assign z__h24621 = z__h24614 ^ wdata[11] ; - assign z__h24628 = z__h24621 ^ wdata[12] ; - assign z__h24635 = z__h24628 ^ wdata[13] ; - assign z__h24642 = z__h24635 ^ wdata[14] ; - assign z__h24649 = z__h24642 ^ wdata[15] ; - assign z__h24656 = z__h24649 ^ wdata[0] ; - assign z__h24663 = z__h24656 ^ wdata[1] ; - assign z__h24670 = z__h24663 ^ wdata[2] ; - assign z__h24677 = z__h24670 ^ wdata[3] ; - assign z__h24684 = z__h24677 ^ wdata[4] ; - assign z__h24691 = z__h24684 ^ wdata[5] ; - assign z__h24698 = z__h24691 ^ wdata[6] ; - assign z__h35143 = swd_controller_data[0] ^ swd_controller_data[1] ; - assign z__h35150 = z__h35143 ^ swd_controller_data[2] ; - assign z__h35157 = z__h35150 ^ swd_controller_data[3] ; - assign z__h35164 = z__h35157 ^ swd_controller_data[4] ; - assign z__h35171 = z__h35164 ^ swd_controller_data[5] ; - assign z__h35178 = z__h35171 ^ swd_controller_data[6] ; - assign z__h35185 = z__h35178 ^ swd_controller_data[7] ; - assign z__h35192 = z__h35185 ^ swd_controller_data[8] ; - assign z__h35199 = z__h35192 ^ swd_controller_data[9] ; - assign z__h35206 = z__h35199 ^ swd_controller_data[10] ; - assign z__h35213 = z__h35206 ^ swd_controller_data[11] ; - assign z__h35220 = z__h35213 ^ swd_controller_data[12] ; - assign z__h35227 = z__h35220 ^ swd_controller_data[13] ; - assign z__h35234 = z__h35227 ^ swd_controller_data[14] ; - assign z__h35241 = z__h35234 ^ swd_controller_data[15] ; - assign z__h35248 = z__h35241 ^ swd_controller_data[16] ; - assign z__h35255 = z__h35248 ^ swd_controller_data[17] ; - assign z__h35262 = z__h35255 ^ swd_controller_data[18] ; - assign z__h35269 = z__h35262 ^ swd_controller_data[19] ; - assign z__h35276 = z__h35269 ^ swd_controller_data[20] ; - assign z__h35283 = z__h35276 ^ swd_controller_data[21] ; - assign z__h35290 = z__h35283 ^ swd_controller_data[22] ; - assign z__h35297 = z__h35290 ^ swd_controller_data[23] ; - assign z__h35304 = z__h35297 ^ swd_controller_data[24] ; - assign z__h35311 = z__h35304 ^ swd_controller_data[25] ; - assign z__h35318 = z__h35311 ^ swd_controller_data[26] ; - assign z__h35325 = z__h35318 ^ swd_controller_data[27] ; - assign z__h35332 = z__h35325 ^ swd_controller_data[28] ; - assign z__h35339 = z__h35332 ^ swd_controller_data[29] ; - assign z__h35346 = z__h35339 ^ swd_controller_data[30] ; - assign z__h35353 = z__h35346 ^ swd_controller_data[31] ; + assign swd_controller_data_2_BIT_0_5_XOR_swd_controll_ETC___d298 = + z__h35551 ^ swd_controller_data[32] ; + assign x__h1438 = _0xE79E__q2[i__h1457[3:0]] ; + assign x__h15006 = swd_controller_cnt - 7'd1 ; + assign x__h20247 = x__h20260 ^ cmd_BITS_1_TO_0__q1[1] ; + assign x__h20260 = x__h20262 ^ cmd_BITS_1_TO_0__q1[0] ; + assign x__h20262 = ~cmd[3] ; + assign x__h21446 = x__h21459 ^ cmd_BITS_1_TO_0__q1[1] ; + assign x__h21459 = cmd[3] ^ cmd_BITS_1_TO_0__q1[0] ; + assign z__h24693 = wdata[24] ^ wdata[25] ; + assign z__h24700 = z__h24693 ^ wdata[26] ; + assign z__h24707 = z__h24700 ^ wdata[27] ; + assign z__h24714 = z__h24707 ^ wdata[28] ; + assign z__h24721 = z__h24714 ^ wdata[29] ; + assign z__h24728 = z__h24721 ^ wdata[30] ; + assign z__h24735 = z__h24728 ^ wdata[31] ; + assign z__h24742 = z__h24735 ^ wdata[16] ; + assign z__h24749 = z__h24742 ^ wdata[17] ; + assign z__h24756 = z__h24749 ^ wdata[18] ; + assign z__h24763 = z__h24756 ^ wdata[19] ; + assign z__h24770 = z__h24763 ^ wdata[20] ; + assign z__h24777 = z__h24770 ^ wdata[21] ; + assign z__h24784 = z__h24777 ^ wdata[22] ; + assign z__h24791 = z__h24784 ^ wdata[23] ; + assign z__h24798 = z__h24791 ^ wdata[8] ; + assign z__h24805 = z__h24798 ^ wdata[9] ; + assign z__h24812 = z__h24805 ^ wdata[10] ; + assign z__h24819 = z__h24812 ^ wdata[11] ; + assign z__h24826 = z__h24819 ^ wdata[12] ; + assign z__h24833 = z__h24826 ^ wdata[13] ; + assign z__h24840 = z__h24833 ^ wdata[14] ; + assign z__h24847 = z__h24840 ^ wdata[15] ; + assign z__h24854 = z__h24847 ^ wdata[0] ; + assign z__h24861 = z__h24854 ^ wdata[1] ; + assign z__h24868 = z__h24861 ^ wdata[2] ; + assign z__h24875 = z__h24868 ^ wdata[3] ; + assign z__h24882 = z__h24875 ^ wdata[4] ; + assign z__h24889 = z__h24882 ^ wdata[5] ; + assign z__h24896 = z__h24889 ^ wdata[6] ; + assign z__h35341 = swd_controller_data[0] ^ swd_controller_data[1] ; + assign z__h35348 = z__h35341 ^ swd_controller_data[2] ; + assign z__h35355 = z__h35348 ^ swd_controller_data[3] ; + assign z__h35362 = z__h35355 ^ swd_controller_data[4] ; + assign z__h35369 = z__h35362 ^ swd_controller_data[5] ; + assign z__h35376 = z__h35369 ^ swd_controller_data[6] ; + assign z__h35383 = z__h35376 ^ swd_controller_data[7] ; + assign z__h35390 = z__h35383 ^ swd_controller_data[8] ; + assign z__h35397 = z__h35390 ^ swd_controller_data[9] ; + assign z__h35404 = z__h35397 ^ swd_controller_data[10] ; + assign z__h35411 = z__h35404 ^ swd_controller_data[11] ; + assign z__h35418 = z__h35411 ^ swd_controller_data[12] ; + assign z__h35425 = z__h35418 ^ swd_controller_data[13] ; + assign z__h35432 = z__h35425 ^ swd_controller_data[14] ; + assign z__h35439 = z__h35432 ^ swd_controller_data[15] ; + assign z__h35446 = z__h35439 ^ swd_controller_data[16] ; + assign z__h35453 = z__h35446 ^ swd_controller_data[17] ; + assign z__h35460 = z__h35453 ^ swd_controller_data[18] ; + assign z__h35467 = z__h35460 ^ swd_controller_data[19] ; + assign z__h35474 = z__h35467 ^ swd_controller_data[20] ; + assign z__h35481 = z__h35474 ^ swd_controller_data[21] ; + assign z__h35488 = z__h35481 ^ swd_controller_data[22] ; + assign z__h35495 = z__h35488 ^ swd_controller_data[23] ; + assign z__h35502 = z__h35495 ^ swd_controller_data[24] ; + assign z__h35509 = z__h35502 ^ swd_controller_data[25] ; + assign z__h35516 = z__h35509 ^ swd_controller_data[26] ; + assign z__h35523 = z__h35516 ^ swd_controller_data[27] ; + assign z__h35530 = z__h35523 ^ swd_controller_data[28] ; + assign z__h35537 = z__h35530 ^ swd_controller_data[29] ; + assign z__h35544 = z__h35537 ^ swd_controller_data[30] ; + assign z__h35551 = z__h35544 ^ swd_controller_data[31] ; // handling of inlined registers