Uploading Bitstream to CW312T-A35 through CW HUSKY and CW313 Target support

Hello,
I’ve been attempting to upload my own IP bitstream to the FPGA on the CW312T. However, the process appears unsuccessful based on the output I’m observing.

To verify the upload, I attempted to use design_1_wrapper.bit, a random bitstream, expecting different behavior. However, the AES capture example continues to run without any issues, suggesting that the bitstream hasn’t been updated.

The hardware configuration I employed:

Given these challenges, I have several questions:

  1. What is the correct procedure for uploading a bitstream to the FPGA in a setup involving HUSKY → CW313 → CW312T-A35?
  2. I’m seeking clarification on the function of the DIP switches on the CW312T. Although I found some information on the NewAE Technology website (CW312T-XC7A35 - NewAE Hardware Product Documentation), I’m finding it difficult to comprehend. Could someone explain this in more detail? I’m relatively new to this field.

What’s the output from running fpga.program()?
The A35 loses its bitstream when powered down, so there is no need to program our bitfile followed by yours; just program yours after a fresh power cycle.

The CW JTAG DIP switches don’t matter unless you’re connecting a JTAG programmer, in which case they control which FPGA pins the JTAG signals are routed to.

If I print the status, it shows “1”

I am trying to upload Bitstream after every fresh power cycle. But nothing changed.

What do you mean by “nothing changed”? If you mean that our AES notebook runs normally, then one of two things has happened:

  1. you programmed our AES demo bitfile instead of your “random” bitfile (maybe you got the bitfiles mixed up?)
  2. your random bitfile behaves like our AES demo bitfile
  1. your random bitfile behaves like our AES demo bitfile

This random bitfile is nowhere related to AES.

  1. you programmed our AES demo bitfile instead of your “random” bitfile (maybe you got the bitfiles mixed up?)
from chipwhisperer.hardware.naeusb.programmer_targetfpga import CW312T_XC7A35T
fpga = CW312T_XC7A35T(scope)
scope.io.hs2 = None
fpga.program("C:/Users/t177h608/Desktop/Game_One_Final/Game_One_Final.runs/impl_1/top_gameOne.bit", sck_speed=10e6)
scope.io.hs2 = "clkgen"
status = fpga.done_state()
print(status)
target = cw.target(scope, cw.targets.CW305, force=True, fpga_id=fpga_id, platform=platform)

This is the exactly different file and project folder I am using. Is there any way that I can mixup? Please help me on this.

Ah-ha! That last cw.target() line re-programs the FPGA with our bitfile.

To avoid that, do this instead:
target = cw.target(scope, cw.targets.CW305, force=False, program=False, platform=target.platform)

Ah-ha! That last cw.target() line re-programs the FPGA with our bitfile.
To avoid that, do this instead:
target = cw.target(scope, cw.targets.CW305, force=False, program=False, platform=target.platform)

as per your suggestion I tried this:

from chipwhisperer.hardware.naeusb.programmer_targetfpga import CW312T_XC7A35T
fpga = CW312T_XC7A35T(scope)
scope.io.hs2 = None
fpga.program("C:/Users/t177h608/Desktop/Game_One_Final/Game_One_Final.runs/impl_1/top_gameOne.bit", sck_speed=10e6)
scope.io.hs2 = "clkgen"
status = fpga.done_state()
if status:
    print("✅ FPGA programmed.")
else:
    print("❌ FPGA Not Programmed")
target = cw.target(scope, cw.targets.CW305, force=False, program=False, platform=target.platform)

But I am getting the following error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[67], line 11
      9 else:
     10     print("❌ FPGA Not Programmed")
---> 11 target = cw.target(scope, cw.targets.CW305, force=False, program=False, platform=target.platform)

File ~\SCA\chipwhisperer\software\chipwhisperer\__init__.py:422, in target(scope, target_type, **kwargs)
    407 """Create a target object and connect to it.
    408 
    409 Args:
   (...)
    419     Connected target object specified by target_type.
    420 """
    421 rtn = target_type()
--> 422 rtn.con(scope, **kwargs)
    424 # need to check
    425 if type(rtn) in (targets.SimpleSerial, targets.SimpleSerial2) \
    426     and scope and scope._getNAEUSB().check_feature("SERIAL_200_BUFFER"):

File ~\SCA\chipwhisperer\software\chipwhisperer\capture\targets\_base.py:65, in TargetTemplate.con(self, scope, **kwargs)
     63 try:
     64     self.connectStatus = True
---> 65     self._con(scope, **kwargs)
     66 except:
     67     self.dis()

TypeError: CW305._con() got an unexpected keyword argument 'program'

I am using develop version of CW github repo

Sorry, the platform=target.platform was a typo.

The proper call is:

target = cw.target(scope, cw.targets.CW305, force=False, program=False, platform=platform)

(where platform should equal ‘ss2_a35’, having been set earlier in the notebook)

If that still doesn’t work, what does cw.targets.CW305._con? show? If you don’t see a program=True argument there, then you’re not actually using the develop branch. You can run cw.__file__ to confirm which CW installation is getting imported.

Finally, here’s a full setup that I’ve checked, to eliminate any other variables:

import chipwhisperer as cw
scope = cw.scope()
scope.default_setup()

scope.io.hs2 = 'clkgen'
platform = 'ss2_a35'

from chipwhisperer.hardware.naeusb.programmer_targetfpga import CW312T_XC7A35T
fpga = CW312T_XC7A35T(scope)

scope.io.hs2 = None
fpga.program('some_bitfile', sck_speed=10e6)
scope.io.hs2 = 'clkgen'

target = cw.target(scope, cw.targets.CW305, force=False, fpga_id=None, platform=platform, program=False)
1 Like

I have another follow-up question.

For Husky and NAE CW312T-A35, when I am printing print(target.platform), it shows ss2_a35 as output.

Is there any way to use cw305_aes.xpr project in this setup? If so, how can I pass the parameters for that?

I tried the following script:

scope.io.hs2 = 'clkgen'
platform = 'cw305'
scope.gain.db = 45 
fpga_id = '35t'

from chipwhisperer.hardware.naeusb.programmer_targetfpga import CW312T_XC7A35T
fpga = CW312T_XC7A35T(scope)

scope.io.hs2 = None
fpga.program("C:/Users/t177h608/SCA/bit_files/cw305_top_A35.bit", sck_speed=10e6)
scope.io.hs2 = 'clkgen'
target = cw.target(scope, cw.targets.CW305, force=False, fpga_id=fpga_id, platform=platform, program=False)

status = fpga.done_state()
print(status)

it is giving me the following error:

--------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
Cell In[35], line 7
      5 fpga.program("C:/Users/t177h608/SCA/bit_files/cw305_top_A35.bit", sck_speed=10e6)
      6 scope.io.hs2 = 'clkgen'
----> 7 target = cw.target(scope, cw.targets.CW305, force=False, fpga_id=fpga_id, platform=platform, program=False)
      9 status = fpga.done_state()
     10 print(status)

File ~\SCA\chipwhisperer\software\chipwhisperer\__init__.py:422, in target(scope, target_type, **kwargs)
    407 """Create a target object and connect to it.
    408 
    409 Args:
   (...)
    419     Connected target object specified by target_type.
    420 """
    421 rtn = target_type()
--> 422 rtn.con(scope, **kwargs)
    424 # need to check
    425 if type(rtn) in (targets.SimpleSerial, targets.SimpleSerial2) \
    426     and scope and scope._getNAEUSB().check_feature("SERIAL_200_BUFFER"):

File ~\SCA\chipwhisperer\software\chipwhisperer\capture\targets\_base.py:65, in TargetTemplate.con(self, scope, **kwargs)
     63 try:
     64     self.connectStatus = True
---> 65     self._con(scope, **kwargs)
     66 except:
     67     self.dis()

File ~\SCA\chipwhisperer\software\chipwhisperer\capture\targets\CW305.py:472, in CW305._con(self, scope, bsfile, force, fpga_id, defines_files, slurp, prog_speed, hw_location, sn, platform, version, program)
    470 self.pll = PLLCDCE906(self._naeusb, ref_freq = 12.0E6, board="CW305")
    471 self.fpga = FPGA(self._naeusb)
--> 472 self._naeusb.con(idProduct=[0xC305], serial_number=sn, hw_location=hw_location)
    473 if not fpga_id is None:
    474     if fpga_id not in ('100t', '35t'):

File ~\SCA\chipwhisperer\software\chipwhisperer\hardware\naeusb\naeusb.py:782, in NAEUSB.con(self, idProduct, connect_to_first, serial_number, hw_location, **kwargs)
    777 def con(self, idProduct : Tuple[int]=(0xACE2,), connect_to_first : bool=False, 
    778     serial_number : Optional[str]=None, hw_location : Optional[Tuple[int, int]]=None, **kwargs) -> int:
    779     """
    780     Connect to device using default VID/PID
    781     """
--> 782     self.usbtx.open(idProduct=idProduct, serial_number=serial_number, connect_to_first=True, hw_location=hw_location)
    785     self.snum=self.usbtx.sn
    786     fwver = self.readFwVersion()

File ~\SCA\chipwhisperer\software\chipwhisperer\hardware\naeusb\naeusb.py:423, in NAEUSB_Backend.open(self, serial_number, idProduct, connect_to_first, hw_location)
    417 def open(self, serial_number : Optional[str]=None, idProduct : Optional[List[int]]=None, 
    418     connect_to_first : bool =False, hw_location : Optional[Tuple[int, int]]=None) -> Optional[usb1.USBDeviceHandle]:
    419     """
    420     Connect to device using default VID/PID
    421     """
--> 423     self.device = self.find(serial_number, idProduct, hw_location=hw_location)
    424     if connect_to_first == False:
    425         return None

File ~\SCA\chipwhisperer\software\chipwhisperer\hardware\naeusb\naeusb.py:390, in NAEUSB_Backend.find(self, serial_number, idProduct, hw_location)
    388 dev_list = self.get_possible_devices(idProduct, attempt_access=(not hw_location))
    389 if len(dev_list) == 0:
--> 390     raise OSError("Could not find ChipWhisperer. Is it connected?")
    392 # if more than one CW, we require a serial number
    393 if hw_location:

OSError: Could not find ChipWhisperer. Is it connected?

No - while the CW305 and CW312-A35 have the same FPGA, they are different boards. The main difference (from the FPGA point of view) is that the CW305 provides a parallel interface to the FPGA, while the 312 does not. Hence, different bitfiles. However it’s the exact same AES Verilog code that’s used for both.