Merge pull request #86 from shaun0927/fix/golden-ref-adc-formula

fix(cosim): align golden_reference ADC sign conversion with RTL
This commit is contained in:
Jason
2026-04-16 11:49:21 +03:00
committed by GitHub
2 changed files with 8 additions and 5 deletions
+6 -3
View File
@@ -291,9 +291,12 @@ class Mixer:
Convert 8-bit unsigned ADC to 18-bit signed. Convert 8-bit unsigned ADC to 18-bit signed.
RTL: adc_signed_w = {1'b0, adc_data, {9{1'b0}}} - RTL: adc_signed_w = {1'b0, adc_data, {9{1'b0}}} -
{1'b0, {8{1'b1}}, {9{1'b0}}} / 2 {1'b0, {8{1'b1}}, {9{1'b0}}} / 2
= (adc_data << 9) - (0xFF << 9) / 2
= (adc_data << 9) - (0xFF << 8) [integer division] Verilog '/' binds tighter than '-', so the division applies
= (adc_data << 9) - 0x7F80 only to the second concatenation:
{1'b0, 8'hFF, 9'b0} = 0x1FE00
0x1FE00 / 2 = 0xFF00 = 65280
Result: (adc_data << 9) - 0xFF00
""" """
adc_data_8bit = adc_data_8bit & 0xFF adc_data_8bit = adc_data_8bit & 0xFF
# {1'b0, adc_data, 9'b0} = adc_data << 9, zero-padded to 18 bits # {1'b0, adc_data, 9'b0} = adc_data << 9, zero-padded to 18 bits
@@ -290,9 +290,9 @@ def run_ddc(adc_samples):
for n in range(n_samples): for n in range(n_samples):
# ADC sign conversion: RTL does offset binary → signed 18-bit # ADC sign conversion: RTL does offset binary → signed 18-bit
# adc_signed_w = {1'b0, adc_data, 9'b0} - {1'b0, 8'hFF, 9'b0}/2 # adc_signed_w = {1'b0, adc_data, 9'b0} - {1'b0, 8'hFF, 9'b0}/2
# Simplified: center around zero, scale to 18-bit # Exact: (adc_val << 9) - 0xFF00, where 0xFF00 = {1'b0,8'hFF,9'b0}/2
adc_val = int(adc_samples[n]) adc_val = int(adc_samples[n])
adc_signed = (adc_val - 128) << 9 # Approximate RTL sign conversion to 18-bit adc_signed = (adc_val << 9) - 0xFF00 # Exact RTL: {1'b0,adc,9'b0} - {1'b0,8'hFF,9'b0}/2
adc_signed = saturate(adc_signed, 18) adc_signed = saturate(adc_signed, 18)
# NCO lookup (ignoring dithering for golden reference) # NCO lookup (ignoring dithering for golden reference)