diff --git a/cynthion/python/src/gateware/analyzer/analyzer.py b/cynthion/python/src/gateware/analyzer/analyzer.py index fc3dc668..6ba020e7 100644 --- a/cynthion/python/src/gateware/analyzer/analyzer.py +++ b/cynthion/python/src/gateware/analyzer/analyzer.py @@ -165,12 +165,12 @@ def elaborate(self, platform): # One byte is popped if the stream is read. m.d.comb += fifo_bytes_popped.eq(self.stream.ready & self.stream.valid) - # On startup, set counts to zero. + # On startup, set counts to just after the start event. with m.If(self.starting): m.d.usb += [ - fifo_byte_count.eq(0), + fifo_byte_count.eq(self.EVENT_SIZE_BYTES), read_byte_addr.eq(0), - write_byte_addr.eq(0), + write_byte_addr.eq(self.EVENT_SIZE_BYTES), fifo_bytes_pending.eq(0), ] # Otherwise, update the count acording to bytes pushed and popped. @@ -205,8 +205,16 @@ def elaborate(self, platform): # AWAIT_START: wait for capture to be enabled, but don't start mid-packet. with m.State("AWAIT_START"): with m.If(self.capture_enable & ~self.utmi.rx_active): + # Capture is being started. m.next = "AWAIT_PACKET" m.d.usb += current_time.eq(0) + # Log a start event indicating the speed in use. + start_event = USBAnalyzerEvent.CAPTURE_START_BASE \ + | self.speed_selection + m.d.comb += [ + write_event .eq(1), + event_code .eq(start_event), + ] # AWAIT_PACKET: capture is enabled, wait for a packet to start. @@ -323,7 +331,7 @@ def elaborate(self, platform): with m.State("FINISH_EVENT"): m.d.comb += [ mem_write_port.addr .eq(next_word_addr + 1), - mem_write_port.data .eq(current_time), + mem_write_port.data .eq(Mux(self.starting, 0, current_time)), mem_write_port.en .eq(0b11) ] m.next = "START" @@ -397,16 +405,21 @@ def test_single_packet(self): # Try to read back the capture data, byte by byte. self.assertEqual((yield self.dut.stream.valid), 1) - # First, we should get a header with the total data length. + # First we should get a start event with a timestamp of zero. + start_event = [0xFF, 0x04, 0x00, 0x00] + + # Next, we should get a header with the total data length. # This should be 0x00, 0x0a; as we captured 10 bytes. - # Next, we should get a timestamp with the cycle count at which + # Then, we should get a timestamp with the cycle count at which # the packet started. This should be 0x00, 0x02. - self.assertEqual((yield self.dut.stream.payload), 0) + packet = [0x00, 0x0a, 0x00, 0x00] + list(range(0, 10)) + + # Validate that we get all of the bytes we expected. + expected_data = start_event + packet + + self.assertEqual((yield self.dut.stream.payload), expected_data[0]) yield self.dut.stream.ready.eq(1) yield - - # Validate that we get all of the bytes of the packet we expected. - expected_data = [0x00, 0x0a, 0x00, 0x00] + list(range(0, 10)) for datum in expected_data: self.assertEqual((yield self.dut.stream.payload), datum) yield @@ -441,16 +454,21 @@ def test_short_packet(self): # Try to read back the capture data, byte by byte. self.assertEqual((yield self.dut.stream.valid), 1) - # First, we should get a header with the total data length. + # First we should get a start event with a timestamp of zero. + start_event = [0xFF, 0x04, 0x00, 0x00] + + # Next, we should get a header with the total data length. # This should be 0x00, 0x01; as we captured 1 byte. - # Next, we should get a timestamp with the cycle count at which + # Then, we should get a timestamp with the cycle count at which # the packet started. This should be 0x00, 0x00. - self.assertEqual((yield self.dut.stream.payload), 0) + packet = [0x00, 0x01, 0x00, 0x00, 0xab] + + # Validate that we get all of the bytes we expected. + expected_data = start_event + packet + + self.assertEqual((yield self.dut.stream.payload), expected_data[0]) yield self.dut.stream.ready.eq(1) yield - - # Validate that we get all of the bytes of the packet we expected. - expected_data = [0x00, 0x01, 0x00, 0x00, 0xab] for datum in expected_data: self.assertEqual((yield self.dut.stream.payload), datum) yield @@ -486,14 +504,17 @@ def test_timestamp_wrap(self): yield self.dut.stream.ready.eq(1) yield - # First, we should get an event with code zero, timestamp 0xFFFF. + # First we should get a start event with a timestamp of zero. + start_event = [0xFF, 0x04, 0x00, 0x00] + + # Then, we should get an event with code zero, timestamp 0xFFFF. rollover_event = [0xFF, 0x00, 0xFF, 0xFF] # Next we should get the packet, with length 1 and timestamp 0x0123. packet = [0x00, 0x01, 0x01, 0x23, 0xAB] # Validate that we get all of the expected bytes. - expected_data = rollover_event + packet + expected_data = start_event + rollover_event + packet for datum in expected_data: self.assertEqual((yield self.dut.stream.payload), datum) yield @@ -583,7 +604,10 @@ def test_simple_analysis(self): # Validate that we got the correct packet out; plus headers. # We waited 10 cycles before starting the packet, so the # timestamp should be 0x00, 0x0a. - for i in [0x00, 0x03, 0x00, 0x0a, 0x2d, 0x00, 0x10]: + start_event = [0xFF, 0x04, 0x00, 0x00] + packet = [0x00, 0x03, 0x00, 0x0a, 0x2d, 0x00, 0x10] + expected_data = start_event + packet + for i in expected_data: self.assertEqual((yield self.analyzer.stream.payload), i) yield