From 1f8562e7769b643e133c184b81a3aefb79900ad5 Mon Sep 17 00:00:00 2001 From: Leon Schoorl Date: Tue, 27 Jun 2023 09:23:38 +0200 Subject: [PATCH 1/3] Add 'testConfig6_200_on_0a_and_0' --- bittide/src/Bittide/ClockControl/Si5395J.hs | 600 ++++++++++++++++++++ 1 file changed, 600 insertions(+) diff --git a/bittide/src/Bittide/ClockControl/Si5395J.hs b/bittide/src/Bittide/ClockControl/Si5395J.hs index 58a43a5ae..f07c51726 100644 --- a/bittide/src/Bittide/ClockControl/Si5395J.hs +++ b/bittide/src/Bittide/ClockControl/Si5395J.hs @@ -1195,3 +1195,603 @@ testConfig6_200_5_20 = Si539xRegisterMap{..} (0x0C, 0x03, 0x00) :> (0x0C, 0x07, 0x00) :> (0x0C, 0x08, 0x00) :> Nil + + +{-| Configuration for Si5395J with + out0a: 200MHz LVDS 1.8V connected to GTH SMA clk input (clk0 on quad 226) + out0: 200MHz LVDS 1.8V connected to User SMA clk input on node 7 only + out9: 20MHZ LVDS 1.8V + out9a: 200MHz LVDS 1.8V + all of them doing 10ppb steps on Finc/Fdec +-} +testConfig6_200_on_0a_and_0 :: Si5395RegisterMap +testConfig6_200_on_0a_and_0 = Si539xRegisterMap{..} + where + configPreamble = (0x0B, 0x24, 0xC0) :> (0x0B, 0x25, 0x00) :> (0x05, 0x40, 0x01) :> Nil + configPostamble = (0x05, 0x14, 0x01) :> (0x00, 0x1C, 0x01) :> (0x05, 0x40, 0x00) :> (0x0B, 0x24, 0xC3) :> (0x0B, 0x25, 0x02) :> Nil + config = + (0x00, 0x06, 0x00) :> + (0x00, 0x07, 0x00) :> + (0x00, 0x08, 0x00) :> + (0x00, 0x0B, 0x68) :> + (0x00, 0x16, 0x02) :> + (0x00, 0x17, 0xDC) :> + (0x00, 0x18, 0xFF) :> + (0x00, 0x19, 0xFF) :> + (0x00, 0x1A, 0xFF) :> + (0x00, 0x2B, 0x02) :> + (0x00, 0x2C, 0x00) :> + (0x00, 0x2D, 0x00) :> + (0x00, 0x2E, 0x00) :> + (0x00, 0x2F, 0x00) :> + (0x00, 0x30, 0x00) :> + (0x00, 0x31, 0x00) :> + (0x00, 0x32, 0x00) :> + (0x00, 0x33, 0x00) :> + (0x00, 0x34, 0x00) :> + (0x00, 0x35, 0x00) :> + (0x00, 0x36, 0x00) :> + (0x00, 0x37, 0x00) :> + (0x00, 0x38, 0x00) :> + (0x00, 0x39, 0x00) :> + (0x00, 0x3A, 0x00) :> + (0x00, 0x3B, 0x00) :> + (0x00, 0x3C, 0x00) :> + (0x00, 0x3D, 0x00) :> + (0x00, 0x3E, 0x00) :> + (0x00, 0x3F, 0x00) :> + (0x00, 0x40, 0x04) :> + (0x00, 0x41, 0x00) :> + (0x00, 0x42, 0x00) :> + (0x00, 0x43, 0x00) :> + (0x00, 0x44, 0x00) :> + (0x00, 0x45, 0x0C) :> + (0x00, 0x46, 0x00) :> + (0x00, 0x47, 0x00) :> + (0x00, 0x48, 0x00) :> + (0x00, 0x49, 0x00) :> + (0x00, 0x4A, 0x00) :> + (0x00, 0x4B, 0x00) :> + (0x00, 0x4C, 0x00) :> + (0x00, 0x4D, 0x00) :> + (0x00, 0x4E, 0x00) :> + (0x00, 0x4F, 0x00) :> + (0x00, 0x50, 0x0F) :> + (0x00, 0x51, 0x00) :> + (0x00, 0x52, 0x00) :> + (0x00, 0x53, 0x00) :> + (0x00, 0x54, 0x00) :> + (0x00, 0x55, 0x00) :> + (0x00, 0x56, 0x00) :> + (0x00, 0x57, 0x00) :> + (0x00, 0x58, 0x00) :> + (0x00, 0x59, 0x00) :> + (0x00, 0x5A, 0x00) :> + (0x00, 0x5B, 0x00) :> + (0x00, 0x5C, 0x00) :> + (0x00, 0x5D, 0x00) :> + (0x00, 0x5E, 0x00) :> + (0x00, 0x5F, 0x00) :> + (0x00, 0x60, 0x00) :> + (0x00, 0x61, 0x00) :> + (0x00, 0x62, 0x00) :> + (0x00, 0x63, 0x00) :> + (0x00, 0x64, 0x00) :> + (0x00, 0x65, 0x00) :> + (0x00, 0x66, 0x00) :> + (0x00, 0x67, 0x00) :> + (0x00, 0x68, 0x00) :> + (0x00, 0x69, 0x00) :> + (0x00, 0x92, 0x00) :> + (0x00, 0x93, 0x00) :> + (0x00, 0x95, 0x00) :> + (0x00, 0x96, 0x00) :> + (0x00, 0x98, 0x00) :> + (0x00, 0x9A, 0x00) :> + (0x00, 0x9B, 0x00) :> + (0x00, 0x9D, 0x00) :> + (0x00, 0x9E, 0x00) :> + (0x00, 0xA0, 0x00) :> + (0x00, 0xA2, 0x00) :> + (0x00, 0xA9, 0x00) :> + (0x00, 0xAA, 0x00) :> + (0x00, 0xAB, 0x00) :> + (0x00, 0xAC, 0x00) :> + (0x00, 0xE5, 0x01) :> + (0x00, 0xEA, 0x00) :> + (0x00, 0xEB, 0x00) :> + (0x00, 0xEC, 0x00) :> + (0x00, 0xED, 0x00) :> + (0x01, 0x02, 0x01) :> + (0x01, 0x03, 0x06) :> + (0x01, 0x04, 0x09) :> + (0x01, 0x05, 0x3E) :> + (0x01, 0x06, 0x18) :> + (0x01, 0x08, 0x06) :> + (0x01, 0x09, 0x09) :> + (0x01, 0x0A, 0x3E) :> + (0x01, 0x0B, 0x18) :> + (0x01, 0x0D, 0x01) :> + (0x01, 0x0E, 0x09) :> + (0x01, 0x0F, 0x3B) :> + (0x01, 0x10, 0x28) :> + (0x01, 0x12, 0x01) :> + (0x01, 0x13, 0x09) :> + (0x01, 0x14, 0x3B) :> + (0x01, 0x15, 0x28) :> + (0x01, 0x17, 0x01) :> + (0x01, 0x18, 0x09) :> + (0x01, 0x19, 0x3B) :> + (0x01, 0x1A, 0x28) :> + (0x01, 0x1C, 0x01) :> + (0x01, 0x1D, 0x09) :> + (0x01, 0x1E, 0x3B) :> + (0x01, 0x1F, 0x28) :> + (0x01, 0x21, 0x01) :> + (0x01, 0x22, 0x09) :> + (0x01, 0x23, 0x3B) :> + (0x01, 0x24, 0x28) :> + (0x01, 0x26, 0x01) :> + (0x01, 0x27, 0x09) :> + (0x01, 0x28, 0x3B) :> + (0x01, 0x29, 0x28) :> + (0x01, 0x2B, 0x01) :> + (0x01, 0x2C, 0x09) :> + (0x01, 0x2D, 0x3B) :> + (0x01, 0x2E, 0x28) :> + (0x01, 0x30, 0x01) :> + (0x01, 0x31, 0x09) :> + (0x01, 0x32, 0x3B) :> + (0x01, 0x33, 0x28) :> + (0x01, 0x35, 0x02) :> + (0x01, 0x36, 0x09) :> + (0x01, 0x37, 0x3E) :> + (0x01, 0x38, 0x19) :> + (0x01, 0x3A, 0x06) :> + (0x01, 0x3B, 0x09) :> + (0x01, 0x3C, 0x3E) :> + (0x01, 0x3D, 0x19) :> + (0x01, 0x3F, 0x00) :> + (0x01, 0x40, 0x00) :> + (0x01, 0x41, 0x40) :> + (0x01, 0x42, 0xFF) :> + (0x02, 0x06, 0x00) :> + (0x02, 0x08, 0x00) :> + (0x02, 0x09, 0x00) :> + (0x02, 0x0A, 0x00) :> + (0x02, 0x0B, 0x00) :> + (0x02, 0x0C, 0x00) :> + (0x02, 0x0D, 0x00) :> + (0x02, 0x0E, 0x00) :> + (0x02, 0x0F, 0x00) :> + (0x02, 0x10, 0x00) :> + (0x02, 0x11, 0x00) :> + (0x02, 0x12, 0x00) :> + (0x02, 0x13, 0x00) :> + (0x02, 0x14, 0x00) :> + (0x02, 0x15, 0x00) :> + (0x02, 0x16, 0x00) :> + (0x02, 0x17, 0x00) :> + (0x02, 0x18, 0x00) :> + (0x02, 0x19, 0x00) :> + (0x02, 0x1A, 0x00) :> + (0x02, 0x1B, 0x00) :> + (0x02, 0x1C, 0x00) :> + (0x02, 0x1D, 0x00) :> + (0x02, 0x1E, 0x00) :> + (0x02, 0x1F, 0x00) :> + (0x02, 0x20, 0x00) :> + (0x02, 0x21, 0x00) :> + (0x02, 0x22, 0x00) :> + (0x02, 0x23, 0x00) :> + (0x02, 0x24, 0x00) :> + (0x02, 0x25, 0x00) :> + (0x02, 0x26, 0x00) :> + (0x02, 0x27, 0x00) :> + (0x02, 0x28, 0x00) :> + (0x02, 0x29, 0x00) :> + (0x02, 0x2A, 0x00) :> + (0x02, 0x2B, 0x00) :> + (0x02, 0x2C, 0x00) :> + (0x02, 0x2D, 0x00) :> + (0x02, 0x2E, 0x00) :> + (0x02, 0x2F, 0x00) :> + (0x02, 0x31, 0x0B) :> + (0x02, 0x32, 0x0B) :> + (0x02, 0x33, 0x0B) :> + (0x02, 0x34, 0x0B) :> + (0x02, 0x35, 0x00) :> + (0x02, 0x36, 0x00) :> + (0x02, 0x37, 0x00) :> + (0x02, 0x38, 0xC0) :> + (0x02, 0x39, 0x89) :> + (0x02, 0x3A, 0x00) :> + (0x02, 0x3B, 0x00) :> + (0x02, 0x3C, 0x00) :> + (0x02, 0x3D, 0x00) :> + (0x02, 0x3E, 0x80) :> + (0x02, 0x47, 0x00) :> + (0x02, 0x48, 0x00) :> + (0x02, 0x49, 0x00) :> + (0x02, 0x4A, 0x00) :> + (0x02, 0x4B, 0x00) :> + (0x02, 0x4C, 0x00) :> + (0x02, 0x4D, 0x00) :> + (0x02, 0x4E, 0x00) :> + (0x02, 0x4F, 0x00) :> + (0x02, 0x50, 0x00) :> + (0x02, 0x51, 0x00) :> + (0x02, 0x52, 0x00) :> + (0x02, 0x53, 0x00) :> + (0x02, 0x54, 0x00) :> + (0x02, 0x55, 0x00) :> + (0x02, 0x56, 0x00) :> + (0x02, 0x57, 0x00) :> + (0x02, 0x58, 0x00) :> + (0x02, 0x59, 0x00) :> + (0x02, 0x5A, 0x00) :> + (0x02, 0x5B, 0x00) :> + (0x02, 0x5C, 0x00) :> + (0x02, 0x5D, 0x00) :> + (0x02, 0x5E, 0x00) :> + (0x02, 0x5F, 0x00) :> + (0x02, 0x60, 0x00) :> + (0x02, 0x61, 0x00) :> + (0x02, 0x62, 0x00) :> + (0x02, 0x63, 0x00) :> + (0x02, 0x64, 0x00) :> + (0x02, 0x65, 0x09) :> + (0x02, 0x66, 0x00) :> + (0x02, 0x67, 0x00) :> + (0x02, 0x68, 0x00) :> + (0x02, 0x69, 0x00) :> + (0x02, 0x6A, 0x00) :> + (0x02, 0x6B, 0x00) :> + (0x02, 0x6C, 0x00) :> + (0x02, 0x6D, 0x00) :> + (0x02, 0x6E, 0x00) :> + (0x02, 0x6F, 0x00) :> + (0x02, 0x70, 0x00) :> + (0x02, 0x71, 0x00) :> + (0x02, 0x72, 0x00) :> + (0x02, 0x8A, 0x00) :> + (0x02, 0x8B, 0x00) :> + (0x02, 0x8C, 0x00) :> + (0x02, 0x8D, 0x00) :> + (0x02, 0x8E, 0x00) :> + (0x02, 0x8F, 0x00) :> + (0x02, 0x90, 0x00) :> + (0x02, 0x91, 0x00) :> + (0x02, 0x92, 0x3F) :> + (0x02, 0x93, 0x2F) :> + (0x02, 0x94, 0x80) :> + (0x02, 0x96, 0x00) :> + (0x02, 0x97, 0x00) :> + (0x02, 0x99, 0x00) :> + (0x02, 0x9D, 0x00) :> + (0x02, 0x9E, 0x00) :> + (0x02, 0x9F, 0x00) :> + (0x02, 0xA9, 0x00) :> + (0x02, 0xAA, 0x00) :> + (0x02, 0xAB, 0x00) :> + (0x02, 0xB7, 0xFF) :> + (0x02, 0xBC, 0x00) :> + (0x03, 0x02, 0x00) :> + (0x03, 0x03, 0x00) :> + (0x03, 0x04, 0x00) :> + (0x03, 0x05, 0xD4) :> + (0x03, 0x06, 0x19) :> + (0x03, 0x07, 0x00) :> + (0x03, 0x08, 0x00) :> + (0x03, 0x09, 0x00) :> + (0x03, 0x0A, 0x00) :> + (0x03, 0x0B, 0xC8) :> + (0x03, 0x0C, 0x00) :> + (0x03, 0x0D, 0x00) :> + (0x03, 0x0E, 0x00) :> + (0x03, 0x0F, 0x00) :> + (0x03, 0x10, 0xD4) :> + (0x03, 0x11, 0x19) :> + (0x03, 0x12, 0x00) :> + (0x03, 0x13, 0x00) :> + (0x03, 0x14, 0x00) :> + (0x03, 0x15, 0x00) :> + (0x03, 0x16, 0xC8) :> + (0x03, 0x17, 0x00) :> + (0x03, 0x18, 0x00) :> + (0x03, 0x19, 0x00) :> + (0x03, 0x1A, 0x00) :> + (0x03, 0x1B, 0x00) :> + (0x03, 0x1C, 0x00) :> + (0x03, 0x1D, 0x00) :> + (0x03, 0x1E, 0x00) :> + (0x03, 0x1F, 0x00) :> + (0x03, 0x20, 0x00) :> + (0x03, 0x21, 0x00) :> + (0x03, 0x22, 0x00) :> + (0x03, 0x23, 0x00) :> + (0x03, 0x24, 0x00) :> + (0x03, 0x25, 0x00) :> + (0x03, 0x26, 0x00) :> + (0x03, 0x27, 0x00) :> + (0x03, 0x28, 0x00) :> + (0x03, 0x29, 0x00) :> + (0x03, 0x2A, 0x00) :> + (0x03, 0x2B, 0x00) :> + (0x03, 0x2C, 0x00) :> + (0x03, 0x2D, 0x00) :> + (0x03, 0x2E, 0x00) :> + (0x03, 0x2F, 0x00) :> + (0x03, 0x30, 0x00) :> + (0x03, 0x31, 0x00) :> + (0x03, 0x32, 0x00) :> + (0x03, 0x33, 0x00) :> + (0x03, 0x34, 0x00) :> + (0x03, 0x35, 0x00) :> + (0x03, 0x36, 0x00) :> + (0x03, 0x37, 0x00) :> + (0x03, 0x38, 0x00) :> + (0x03, 0x39, 0x1C) :> + (0x03, 0x3B, 0x55) :> + (0x03, 0x3C, 0x04) :> + (0x03, 0x3D, 0x00) :> + (0x03, 0x3E, 0x00) :> + (0x03, 0x3F, 0x00) :> + (0x03, 0x40, 0x00) :> + (0x03, 0x41, 0x55) :> + (0x03, 0x42, 0x04) :> + (0x03, 0x43, 0x00) :> + (0x03, 0x44, 0x00) :> + (0x03, 0x45, 0x00) :> + (0x03, 0x46, 0x00) :> + (0x03, 0x47, 0x00) :> + (0x03, 0x48, 0x00) :> + (0x03, 0x49, 0x00) :> + (0x03, 0x4A, 0x00) :> + (0x03, 0x4B, 0x00) :> + (0x03, 0x4C, 0x00) :> + (0x03, 0x4D, 0x00) :> + (0x03, 0x4E, 0x00) :> + (0x03, 0x4F, 0x00) :> + (0x03, 0x50, 0x00) :> + (0x03, 0x51, 0x00) :> + (0x03, 0x52, 0x00) :> + (0x03, 0x53, 0x00) :> + (0x03, 0x54, 0x00) :> + (0x03, 0x55, 0x00) :> + (0x03, 0x56, 0x00) :> + (0x03, 0x57, 0x00) :> + (0x03, 0x58, 0x00) :> + (0x03, 0x59, 0x00) :> + (0x03, 0x5A, 0x00) :> + (0x03, 0x5B, 0x00) :> + (0x03, 0x5C, 0x00) :> + (0x03, 0x5D, 0x00) :> + (0x03, 0x5E, 0x00) :> + (0x03, 0x5F, 0x00) :> + (0x03, 0x60, 0x00) :> + (0x03, 0x61, 0x00) :> + (0x03, 0x62, 0x00) :> + (0x04, 0x87, 0x00) :> + (0x05, 0x08, 0x00) :> + (0x05, 0x09, 0x00) :> + (0x05, 0x0A, 0x00) :> + (0x05, 0x0B, 0x00) :> + (0x05, 0x0C, 0x00) :> + (0x05, 0x0D, 0x00) :> + (0x05, 0x0E, 0x00) :> + (0x05, 0x0F, 0x00) :> + (0x05, 0x10, 0x00) :> + (0x05, 0x11, 0x00) :> + (0x05, 0x12, 0x00) :> + (0x05, 0x13, 0x00) :> + (0x05, 0x15, 0x00) :> + (0x05, 0x16, 0x00) :> + (0x05, 0x17, 0x00) :> + (0x05, 0x18, 0x00) :> + (0x05, 0x19, 0x00) :> + (0x05, 0x1A, 0x00) :> + (0x05, 0x1B, 0x00) :> + (0x05, 0x1C, 0x00) :> + (0x05, 0x1D, 0x00) :> + (0x05, 0x1E, 0x00) :> + (0x05, 0x1F, 0x00) :> + (0x05, 0x21, 0x2B) :> + (0x05, 0x2A, 0x00) :> + (0x05, 0x2B, 0x01) :> + (0x05, 0x2C, 0x0F) :> + (0x05, 0x2D, 0x03) :> + (0x05, 0x2E, 0x00) :> + (0x05, 0x2F, 0x00) :> + (0x05, 0x31, 0x00) :> + (0x05, 0x32, 0x00) :> + (0x05, 0x33, 0x04) :> + (0x05, 0x34, 0x00) :> + (0x05, 0x35, 0x01) :> + (0x05, 0x36, 0x06) :> + (0x05, 0x37, 0x00) :> + (0x05, 0x38, 0x00) :> + (0x05, 0x39, 0x00) :> + (0x05, 0x3D, 0x0A) :> + (0x05, 0x3E, 0x06) :> + (0x05, 0x88, 0x00) :> + (0x05, 0x89, 0x0C) :> + (0x05, 0x8A, 0x00) :> + (0x05, 0x8B, 0x00) :> + (0x05, 0x8C, 0x00) :> + (0x05, 0x8D, 0x00) :> + (0x05, 0x9B, 0x18) :> + (0x05, 0x9C, 0x0C) :> + (0x05, 0x9D, 0x00) :> + (0x05, 0x9E, 0x00) :> + (0x05, 0x9F, 0x00) :> + (0x05, 0xA0, 0x00) :> + (0x05, 0xA1, 0x00) :> + (0x05, 0xA2, 0x00) :> + (0x05, 0xA4, 0x20) :> + (0x05, 0xA5, 0x00) :> + (0x05, 0xA6, 0x00) :> + (0x05, 0xAC, 0x00) :> + (0x05, 0xAD, 0x00) :> + (0x05, 0xAE, 0x00) :> + (0x05, 0xB1, 0x00) :> + (0x05, 0xB2, 0x00) :> + (0x08, 0x02, 0x35) :> + (0x08, 0x03, 0x05) :> + (0x08, 0x04, 0x01) :> + (0x08, 0x05, 0x00) :> + (0x08, 0x06, 0x00) :> + (0x08, 0x07, 0x00) :> + (0x08, 0x08, 0x00) :> + (0x08, 0x09, 0x00) :> + (0x08, 0x0A, 0x00) :> + (0x08, 0x0B, 0x00) :> + (0x08, 0x0C, 0x00) :> + (0x08, 0x0D, 0x00) :> + (0x08, 0x0E, 0x00) :> + (0x08, 0x0F, 0x00) :> + (0x08, 0x10, 0x00) :> + (0x08, 0x11, 0x00) :> + (0x08, 0x12, 0x00) :> + (0x08, 0x13, 0x00) :> + (0x08, 0x14, 0x00) :> + (0x08, 0x15, 0x00) :> + (0x08, 0x16, 0x00) :> + (0x08, 0x17, 0x00) :> + (0x08, 0x18, 0x00) :> + (0x08, 0x19, 0x00) :> + (0x08, 0x1A, 0x00) :> + (0x08, 0x1B, 0x00) :> + (0x08, 0x1C, 0x00) :> + (0x08, 0x1D, 0x00) :> + (0x08, 0x1E, 0x00) :> + (0x08, 0x1F, 0x00) :> + (0x08, 0x20, 0x00) :> + (0x08, 0x21, 0x00) :> + (0x08, 0x22, 0x00) :> + (0x08, 0x23, 0x00) :> + (0x08, 0x24, 0x00) :> + (0x08, 0x25, 0x00) :> + (0x08, 0x26, 0x00) :> + (0x08, 0x27, 0x00) :> + (0x08, 0x28, 0x00) :> + (0x08, 0x29, 0x00) :> + (0x08, 0x2A, 0x00) :> + (0x08, 0x2B, 0x00) :> + (0x08, 0x2C, 0x00) :> + (0x08, 0x2D, 0x00) :> + (0x08, 0x2E, 0x00) :> + (0x08, 0x2F, 0x00) :> + (0x08, 0x30, 0x00) :> + (0x08, 0x31, 0x00) :> + (0x08, 0x32, 0x00) :> + (0x08, 0x33, 0x00) :> + (0x08, 0x34, 0x00) :> + (0x08, 0x35, 0x00) :> + (0x08, 0x36, 0x00) :> + (0x08, 0x37, 0x00) :> + (0x08, 0x38, 0x00) :> + (0x08, 0x39, 0x00) :> + (0x08, 0x3A, 0x00) :> + (0x08, 0x3B, 0x00) :> + (0x08, 0x3C, 0x00) :> + (0x08, 0x3D, 0x00) :> + (0x08, 0x3E, 0x00) :> + (0x08, 0x3F, 0x00) :> + (0x08, 0x40, 0x00) :> + (0x08, 0x41, 0x00) :> + (0x08, 0x42, 0x00) :> + (0x08, 0x43, 0x00) :> + (0x08, 0x44, 0x00) :> + (0x08, 0x45, 0x00) :> + (0x08, 0x46, 0x00) :> + (0x08, 0x47, 0x00) :> + (0x08, 0x48, 0x00) :> + (0x08, 0x49, 0x00) :> + (0x08, 0x4A, 0x00) :> + (0x08, 0x4B, 0x00) :> + (0x08, 0x4C, 0x00) :> + (0x08, 0x4D, 0x00) :> + (0x08, 0x4E, 0x00) :> + (0x08, 0x4F, 0x00) :> + (0x08, 0x50, 0x00) :> + (0x08, 0x51, 0x00) :> + (0x08, 0x52, 0x00) :> + (0x08, 0x53, 0x00) :> + (0x08, 0x54, 0x00) :> + (0x08, 0x55, 0x00) :> + (0x08, 0x56, 0x00) :> + (0x08, 0x57, 0x00) :> + (0x08, 0x58, 0x00) :> + (0x08, 0x59, 0x00) :> + (0x08, 0x5A, 0x00) :> + (0x08, 0x5B, 0x00) :> + (0x08, 0x5C, 0x00) :> + (0x08, 0x5D, 0x00) :> + (0x08, 0x5E, 0x00) :> + (0x08, 0x5F, 0x00) :> + (0x08, 0x60, 0x00) :> + (0x08, 0x61, 0x00) :> + (0x09, 0x0E, 0x02) :> + (0x09, 0x43, 0x01) :> + (0x09, 0x49, 0x00) :> + (0x09, 0x4A, 0x00) :> + (0x09, 0x4E, 0x49) :> + (0x09, 0x4F, 0xF2) :> + (0x09, 0x5E, 0x00) :> + (0x0A, 0x02, 0x00) :> + (0x0A, 0x03, 0x03) :> + (0x0A, 0x04, 0x00) :> + (0x0A, 0x05, 0x03) :> + (0x0A, 0x14, 0x00) :> + (0x0A, 0x1A, 0x00) :> + (0x0A, 0x20, 0x00) :> + (0x0A, 0x26, 0x00) :> + (0x0A, 0x2C, 0x00) :> + (0x0A, 0x38, 0x00) :> + (0x0A, 0x39, 0x00) :> + (0x0A, 0x3A, 0x00) :> + (0x0A, 0x3C, 0x00) :> + (0x0A, 0x3D, 0x00) :> + (0x0A, 0x3E, 0x00) :> + (0x0A, 0x40, 0x00) :> + (0x0A, 0x41, 0x00) :> + (0x0A, 0x42, 0x00) :> + (0x0A, 0x44, 0x00) :> + (0x0A, 0x45, 0x00) :> + (0x0A, 0x46, 0x00) :> + (0x0A, 0x48, 0x00) :> + (0x0A, 0x49, 0x00) :> + (0x0A, 0x4A, 0x00) :> + (0x0A, 0x4C, 0x00) :> + (0x0A, 0x4D, 0x00) :> + (0x0A, 0x4E, 0x00) :> + (0x0A, 0x4F, 0x00) :> + (0x0A, 0x50, 0x00) :> + (0x0A, 0x51, 0x00) :> + (0x0A, 0x52, 0x00) :> + (0x0A, 0x53, 0x00) :> + (0x0A, 0x54, 0x00) :> + (0x0A, 0x55, 0x00) :> + (0x0A, 0x56, 0x00) :> + (0x0A, 0x57, 0x00) :> + (0x0A, 0x58, 0x00) :> + (0x0A, 0x59, 0x00) :> + (0x0A, 0x5A, 0x00) :> + (0x0A, 0x5B, 0x00) :> + (0x0A, 0x5C, 0x00) :> + (0x0A, 0x5D, 0x00) :> + (0x0A, 0x5E, 0x00) :> + (0x0A, 0x5F, 0x00) :> + (0x0B, 0x44, 0x0F) :> + (0x0B, 0x46, 0x00) :> + (0x0B, 0x47, 0x0F) :> + (0x0B, 0x48, 0x0F) :> + (0x0B, 0x4A, 0x1C) :> + (0x0B, 0x57, 0x0E) :> + (0x0B, 0x58, 0x01) :> + (0x0C, 0x02, 0x03) :> + (0x0C, 0x03, 0x00) :> + (0x0C, 0x07, 0x00) :> + (0x0C, 0x08, 0x00) :> + Nil From ff7dc6a6f8dbc813053d2240927c797454f83531 Mon Sep 17 00:00:00 2001 From: Martijn Bastiaan Date: Fri, 7 Jul 2023 16:20:49 +0200 Subject: [PATCH 2/3] Increase hardware test timeout to 60 seconds --- bittide-instances/data/tcl/HardwareTest.tcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bittide-instances/data/tcl/HardwareTest.tcl b/bittide-instances/data/tcl/HardwareTest.tcl index bf9e1cdf4..6b27c98b2 100644 --- a/bittide-instances/data/tcl/HardwareTest.tcl +++ b/bittide-instances/data/tcl/HardwareTest.tcl @@ -17,7 +17,7 @@ set fpga_ids { # Timeout specifying how long we should wait for a test to finish before # considering it a failed test. -set test_timeout_ms 1000 +set test_timeout_ms 60000 # Timeout specifying how long to wait for hardware targets (FPGAs) to become # available in the hardware server. From e62f669327b2dea10be6bd0658f4470653200d83 Mon Sep 17 00:00:00 2001 From: Martijn Bastiaan Date: Thu, 6 Jul 2023 16:14:08 +0200 Subject: [PATCH 3/3] Add FINC/FDEC test --- .github/synthesis/all.json | 15 +- .github/synthesis/staging.json | 5 +- .github/workflows/ci.yml | 2 +- bittide-extra/bittide-extra.cabal | 2 + bittide-extra/src/Clash/Reset/Extra.hs | 56 ++++ bittide-extra/src/Clash/Sized/Vector/Extra.hs | 22 ++ bittide-instances/bin/Shake.hs | 27 +- bittide-instances/bittide-instances.cabal | 3 + .../data/constraints/fincFdecTests.xdc | 44 +++ .../src/Bittide/Instances/Tests/FincFdec.hs | 259 ++++++++++++++++++ bittide/src/Bittide/ClockControl.hs | 45 ++- bittide/src/Bittide/ClockControl/Si539xSpi.hs | 8 +- 12 files changed, 465 insertions(+), 23 deletions(-) create mode 100644 bittide-extra/src/Clash/Reset/Extra.hs create mode 100644 bittide-extra/src/Clash/Sized/Vector/Extra.hs create mode 100644 bittide-instances/data/constraints/fincFdecTests.xdc create mode 100644 bittide-instances/src/Bittide/Instances/Tests/FincFdec.hs diff --git a/.github/synthesis/all.json b/.github/synthesis/all.json index 0540eaa4b..2840a55f2 100644 --- a/.github/synthesis/all.json +++ b/.github/synthesis/all.json @@ -1,18 +1,21 @@ [ {"top": "callisto3", "stage": "netlist"}, - {"top": "counterReducedPins", "stage": "netlist"}, {"top": "clockControlDemo0", "stage": "bitstream"}, {"top": "clockControlDemo1", "stage": "bitstream"}, + {"top": "counterReducedPins", "stage": "netlist"}, {"top": "elasticBuffer5", "stage": "netlist"}, {"top": "extendedHardwareInTheLoopTest", "stage": "test"}, - {"top": "gatherUnit1K", "stage": "hdl" }, + {"top": "gatherUnit1K", "stage": "hdl"}, {"top": "gatherUnit1KReducedPins", "stage": "netlist"}, - {"top": "simpleHardwareInTheLoopTest", "stage": "test"}, {"top": "safeDffSynchronizer", "stage": "netlist"}, - {"top": "scatterUnit1K", "stage": "hdl" }, + {"top": "scatterUnit1K", "stage": "hdl"}, {"top": "scatterUnit1KReducedPins", "stage": "netlist"}, {"top": "si5391Spi", "stage": "netlist"}, {"top": "stabilityChecker_3_1M", "stage": "netlist"}, - {"top": "switchCalendar1k", "stage": "hdl" }, - {"top": "switchCalendar1kReducedPins", "stage": "netlist"} + {"top": "switchCalendar1k", "stage": "hdl"}, + {"top": "switchCalendar1kReducedPins", "stage": "netlist"}, + + {"top": "extendedHardwareInTheLoopTest", "stage": "test", "targets": "All" }, + {"top": "fincFdecTests", "stage": "test", "targets": "Specific [-1]"}, + {"top": "simpleHardwareInTheLoopTest", "stage": "test", "targets": "All" } ] diff --git a/.github/synthesis/staging.json b/.github/synthesis/staging.json index cbb1305c2..22278834e 100644 --- a/.github/synthesis/staging.json +++ b/.github/synthesis/staging.json @@ -1,5 +1,6 @@ [ {"top": "clockControlDemo0", "stage": "bitstream"}, - {"top": "simpleHardwareInTheLoopTest", "stage": "test"}, - {"top": "extendedHardwareInTheLoopTest", "stage": "test"} + {"top": "extendedHardwareInTheLoopTest", "stage": "test", "targets": "All"}, + {"top": "fincFdecTests", "stage": "test", "targets": "Specific [-1]"}, + {"top": "simpleHardwareInTheLoopTest", "stage": "test", "targets": "All"} ] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b83804b8c..14d8af67f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -731,7 +731,7 @@ jobs: dir=$(ls _build/vivado | grep -E '\.${{ matrix.target.top }}$') tcl_test=_build/vivado/"${dir}"/run_hardware_test.tcl tcl_program=_build/vivado/"${dir}"/run_board_program.tcl - cabal run shake -- "${tcl_test}" "${tcl_program}" --hardware-targets=All + cabal run shake -- "${tcl_test}" "${tcl_program}" --hardware-targets="${{ matrix.target.targets }}" fi - name: Archive build artifacts diff --git a/bittide-extra/bittide-extra.cabal b/bittide-extra/bittide-extra.cabal index 3e12762ec..53e2a493a 100644 --- a/bittide-extra/bittide-extra.cabal +++ b/bittide-extra/bittide-extra.cabal @@ -75,6 +75,8 @@ library exposed-modules: Bittide.Extra.Maybe Bittide.Extra.Wishbone + Clash.Reset.Extra + Clash.Sized.Vector.Extra test-suite doctests type: exitcode-stdio-1.0 diff --git a/bittide-extra/src/Clash/Reset/Extra.hs b/bittide-extra/src/Clash/Reset/Extra.hs new file mode 100644 index 000000000..d166ad996 --- /dev/null +++ b/bittide-extra/src/Clash/Reset/Extra.hs @@ -0,0 +1,56 @@ +-- SPDX-FileCopyrightText: 2022-2023 Google LLC +-- +-- SPDX-License-Identifier: Apache-2.0 + +module Clash.Reset.Extra where + +import Clash.Explicit.Prelude + +-- TODO: Remove these functions after merging clash-compiler#2539 + +-- | A reset that is never asserted +noReset :: KnownDomain dom => Reset dom +noReset = unsafeFromActiveHigh (pure False) + +-- | Output reset will be asserted when either one of the input resets is +-- asserted +orReset :: + forall dom . + ( KnownDomain dom + , DomainResetKind dom ~ 'Synchronous ) => + Reset dom -> + Reset dom -> + Reset dom +orReset = unsafeOrReset + +-- | Output reset will be asserted when both input resets are asserted +andReset :: + forall dom . + ( KnownDomain dom + , DomainResetKind dom ~ 'Synchronous ) => + Reset dom -> + Reset dom -> + Reset dom +andReset = unsafeAndReset + +-- | Output reset will be asserted when both input resets are asserted. This +-- function is considered unsafe because it can be used on domains with +-- components whose resets are level sensitive, while use of this function can +-- introduce glitches. +unsafeAndReset :: forall dom. KnownDomain dom => Reset dom -> Reset dom -> Reset dom +unsafeAndReset (unsafeFromReset -> rst0) (unsafeFromReset -> rst1) = + unsafeToReset $ + case resetPolarity @dom of + SActiveHigh -> rst0 .&&. rst1 + SActiveLow -> rst0 .||. rst1 + +-- | Output reset will be asserted when either one of the input resets is +-- asserted. This function is considered unsafe because it can be used on +-- domains with components whose resets are level sensitive, while use of this +-- function can introduce glitches. +unsafeOrReset :: forall dom. KnownDomain dom => Reset dom -> Reset dom -> Reset dom +unsafeOrReset (unsafeFromReset -> rst0) (unsafeFromReset -> rst1) = + unsafeToReset $ + case resetPolarity @dom of + SActiveHigh -> rst0 .||. rst1 + SActiveLow -> rst0 .&&. rst1 diff --git a/bittide-extra/src/Clash/Sized/Vector/Extra.hs b/bittide-extra/src/Clash/Sized/Vector/Extra.hs new file mode 100644 index 000000000..f453ad668 --- /dev/null +++ b/bittide-extra/src/Clash/Sized/Vector/Extra.hs @@ -0,0 +1,22 @@ +-- SPDX-FileCopyrightText: 2022-2023 Google LLC +-- +-- SPDX-License-Identifier: Apache-2.0 + +module Clash.Sized.Vector.Extra where + +import Clash.Explicit.Prelude +import Data.Maybe (fromMaybe) + +-- | Finds first element in given vector matching the predicate. Returns +-- 'Nothing' if no element satisfied the predicate. +find :: KnownNat n => (a -> Bool) -> Vec n a -> Maybe a +find f = foldl (<|>) Nothing . map go + where + go a + | f a = Just a + | otherwise = Nothing + +-- | Finds first element in given vector matching the predicate. Returns a +-- default element (the first argument) if no element satisfied the predicate. +findWithDefault :: KnownNat n => a -> (a -> Bool) -> Vec n a -> a +findWithDefault a f = fromMaybe a . find f diff --git a/bittide-instances/bin/Shake.hs b/bittide-instances/bin/Shake.hs index 9c65dc5d4..79725bc40 100644 --- a/bittide-instances/bin/Shake.hs +++ b/bittide-instances/bin/Shake.hs @@ -36,6 +36,9 @@ import qualified Bittide.Instances.ScatterGather as ScatterGather import qualified Bittide.Instances.Si539xSpi as Si539xSpi import qualified Bittide.Instances.StabilityChecker as StabilityChecker import qualified Bittide.Instances.Synchronizer as Synchronizer + +import qualified Bittide.Instances.Tests.FincFdec as FincFdec + import qualified Clash.Util.Interpolate as I import qualified Language.Haskell.TH as TH import qualified System.Directory as Directory @@ -159,6 +162,14 @@ defTarget name = Target , targetHasTest = False } +testTarget :: TH.Name -> Target +testTarget name = Target + { targetName = name + , targetHasXdc = True + , targetHasVio = True + , targetHasTest = True + } + enforceValidTarget :: Target -> Target enforceValidTarget target@Target{..} | targetHasTest && not targetHasVio = @@ -170,17 +181,7 @@ enforceValidTarget target@Target{..} -- | All synthesizable targets targets :: [Target] targets = map enforceValidTarget - [ (defTarget 'BoardTest.simpleHardwareInTheLoopTest) - { targetHasXdc = True - , targetHasVio = True - , targetHasTest = True - } - , (defTarget 'BoardTest.extendedHardwareInTheLoopTest) - { targetHasXdc = True - , targetHasVio = True - , targetHasTest = True - } - , defTarget 'Calendar.switchCalendar1k + [ defTarget 'Calendar.switchCalendar1k , defTarget 'Calendar.switchCalendar1kReducedPins , defTarget 'ClockControl.callisto3 , defTarget 'Counter.counterReducedPins @@ -195,6 +196,10 @@ targets = map enforceValidTarget , defTarget 'Si539xSpi.si5391Spi , defTarget 'StabilityChecker.stabilityChecker_3_1M , defTarget 'Synchronizer.safeDffSynchronizer + + , testTarget 'BoardTest.extendedHardwareInTheLoopTest + , testTarget 'BoardTest.simpleHardwareInTheLoopTest + , testTarget 'FincFdec.fincFdecTests ] shakeOpts :: ShakeOptions diff --git a/bittide-instances/bittide-instances.cabal b/bittide-instances/bittide-instances.cabal index 03bdf47c0..f828be767 100644 --- a/bittide-instances/bittide-instances.cabal +++ b/bittide-instances/bittide-instances.cabal @@ -111,6 +111,9 @@ library Bittide.Instances.StabilityChecker Bittide.Instances.Synchronizer + -- Hardware-in-the-loop tests + Bittide.Instances.Tests.FincFdec + Clash.Shake.Extra Clash.Shake.Flags Clash.Shake.Vivado diff --git a/bittide-instances/data/constraints/fincFdecTests.xdc b/bittide-instances/data/constraints/fincFdecTests.xdc new file mode 100644 index 000000000..b55c018cb --- /dev/null +++ b/bittide-instances/data/constraints/fincFdecTests.xdc @@ -0,0 +1,44 @@ +# SPDX-FileCopyrightText: 2022-2023 Google LLC +# +# SPDX-License-Identifier: Apache-2.0 +# +# NOTE: This configuration is only valid for the leftmost FPGA in the demo rack. +# +# Color | FPGA pin | LVLShift | Connection +# --------|---------------|---------------|--------- +# Grey | PMOD0_0 | IO1 | SWDIO +# Blue | PMOD0_1 | IO2 | FINC +# Yellow | PMOD0_2 | IO3 | MOSI/SDIO +# Red | PMOD0_3 | IO4 | SCLK +# White | PMOD0_4 | IO5 | SWCLK +# Purple | PMOD0_5 | IO6 | FDEC +# Green | PMOD0_6 | IO7 | CSB +# Orange | PMOD0_7 | IO8 | MISO/SDO +# Black | Not connected | Not connected | GND (SWD) +# Brown | PMOD_GND | GND | GND (SPI) +# +# The data wire of the external reset button is connected to PMOD1_3. + + +# CLK_125MHZ +set_property BOARD_PART_PIN sysclk_125_p [get_ports {CLK_125MHZ_p}] +set_property BOARD_PART_PIN sysclk_125_n [get_ports {CLK_125MHZ_n}] + +# USER_SMA_CLOCK +set_property -dict {IOSTANDARD LVDS PACKAGE_PIN D23} [get_ports {USER_SMA_CLOCK_p}] +set_property -dict {IOSTANDARD LVDS PACKAGE_PIN C23} [get_ports {USER_SMA_CLOCK_n}] + +# GPIO_LED_0_LS +set_property BOARD_PART_PIN GPIO_LED_0_LS [get_ports {done}] +# GPIO_LED_1_LS +set_property BOARD_PART_PIN GPIO_LED_1_LS [get_ports {success}] + +# PMOD0_[0..7] +# set_property -dict {IOSTANDARD LVCMOS12 PACKAGE_PIN AK25} [get_ports {SWDIO}] +set_property -dict {IOSTANDARD LVCMOS12 PACKAGE_PIN AN21} [get_ports {FINC}] +set_property -dict {IOSTANDARD LVCMOS12 PACKAGE_PIN AH18} [get_ports {MOSI}] +set_property -dict {IOSTANDARD LVCMOS12 PACKAGE_PIN AM19} [get_ports {SCLK}] +# set_property -dict {IOSTANDARD LVCMOS12 PACKAGE_PIN AE26} [get_ports {SWCLK}] +set_property -dict {IOSTANDARD LVCMOS12 PACKAGE_PIN AF25} [get_ports {FDEC}] +set_property -dict {IOSTANDARD LVCMOS12 PACKAGE_PIN AE21} [get_ports {CSB}] +set_property -dict {IOSTANDARD LVCMOS12 PACKAGE_PIN AM17} [get_ports {MISO}] diff --git a/bittide-instances/src/Bittide/Instances/Tests/FincFdec.hs b/bittide-instances/src/Bittide/Instances/Tests/FincFdec.hs new file mode 100644 index 000000000..6cdcb9f36 --- /dev/null +++ b/bittide-instances/src/Bittide/Instances/Tests/FincFdec.hs @@ -0,0 +1,259 @@ +-- SPDX-FileCopyrightText: 2022-2023 Google LLC +-- +-- SPDX-License-Identifier: Apache-2.0 + +{-# LANGUAGE NumericUnderscores #-} + +-- | A couple of tests testing clock board programming, and subsequently the +-- FINC and FDEC pins. +module Bittide.Instances.Tests.FincFdec where + +import Clash.Annotations.TH (makeTopEntity) +import Clash.Cores.Xilinx.Extra (ibufds) +import Clash.Cores.Xilinx.VIO (vioProbe) +import Clash.Cores.Xilinx.Xpm.Cdc.Single (xpmCdcSingle) +import Clash.Explicit.Prelude +import Clash.Prelude (withClockResetEnable) +import Clash.Reset.Extra (orReset, noReset) +import Clash.Sized.Vector.Extra (findWithDefault) +import Clash.Xilinx.ClockGen (clockWizardDifferential) + +import Bittide.Arithmetic.Time +import Bittide.Counter (domainDiffCounter) +import Bittide.ClockControl (SpeedChange(NoChange, SlowDown, SpeedUp), speedChangeToFincFdec) +import Bittide.ClockControl.Si539xSpi (si539xSpi, ConfigState(Finished)) +import Bittide.Instances.Domains + +import qualified Bittide.ClockControl.Si5395J as Si5395J + +data TestState = Busy | Fail | Success +data Test + -- | Keep pressing FDEC, see if counter falls below certain threshold + = FDec + -- | Keep pressing FINC, see if counter exceeds certain threshold + | FInc + -- | 'FDec' test followed by an 'FInc' one + | FDecInc + -- | 'FInc' test followed by an 'FDec' one + | FIncDec + deriving (Enum, Generic, NFDataX) + +-- | Lists all contructors of 'Test' +allTests :: Vec 4 Test +allTests = FDec :> FInc :> FDecInc :> FIncDec :> Nil + +-- | Counter threshold after which a test is considered passed/failed. In theory +-- clocks can diverge at +-20 kHz (at 200 MHz), which gives the tests 500 ms to +-- adjust their clocks - which should be plenty. +threshold :: Signed 32 +threshold = 20_000 + +testStateToDoneSuccess :: TestState -> (Bool, Bool) +testStateToDoneSuccess = \case + Busy -> (False, False) + Fail -> (True, False) + Success -> (True, True) + +goFincFdecTests :: + Clock Basic200A -> + Reset Basic200A -> + Clock Basic200B -> + Signal Basic200A Test -> + "MISO" ::: Signal Basic200A Bit -> -- SPI + "" ::: + ( Signal Basic200A TestState + + -- Freq increase / freq decrease request to clock board + , "" ::: + ( "FINC" ::: Signal Basic200A Bool + , "FDEC" ::: Signal Basic200A Bool + ) + + -- SPI to clock board: + , "" ::: + ( "SCLK" ::: Signal Basic200A Bool + , "MOSI" ::: Signal Basic200A Bit + , "CSB" ::: Signal Basic200A Bool + ) + + -- Debug signals: + , "" ::: + ( "SPI_BUSY" ::: Signal Basic200A Bool + , "SPI_STATE" ::: Signal Basic200A (BitVector 40) + , "SI_LOCKED" ::: Signal Basic200A Bool + , "COUNTER_ACTIVE" ::: Signal Basic200A Bool + , "COUNTER" ::: Signal Basic200A (Signed 32) + ) + ) +goFincFdecTests clk rst clkControlled testSelect miso = + (testResult, fIncDec, spiOut, debugSignals) + where + debugSignals = (spiBusy, pack <$> spiState, siClkLocked, counterActive, counter) + + (_, spiBusy, spiState@(fmap (==Finished) -> siClkLocked), spiOut) = + withClockResetEnable clk rst enableGen $ + si539xSpi + Si5395J.testConfig6_200_on_0a_and_0 + (SNat @(Microseconds 1)) + (pure Nothing) + miso + + rstTest = unsafeFromActiveLow siClkLocked + + rstControlled = + unsafeFromActiveLow $ + xpmCdcSingle clk clkControlled $ -- improvised reset syncer + unsafeToActiveLow rst + + (counter, counterActive) = + unbundle $ + -- Note that in a "real" Bittide system the clocks would be wired up the + -- other way around: the controlled domain would be the target domain. We + -- don't do that here because we know 'rstControlled' will come out of + -- reset much earlier than 'rstTest'. Doing it the "proper" way would + -- therefore introduce extra complexity, without adding to the test's + -- coverage. + domainDiffCounter clkControlled rstControlled clk rstTest + + fIncDec = unbundle $ speedChangeToFincFdec clk rstTest fIncDecRequest + + (fIncDecRequest, testResult) = unbundle $ + (!!) + <$> bundle (fDecResult :> fIncResult :> fDecIncResult :> fIncDecResult :> Nil) + <*> fmap fromEnum testSelect + + fDecResult = goFdec <$> counter + fIncResult = goFinc <$> counter + fDecIncResult = mealy clk rstTest enableGen goFdecFinc FDec counter + fIncDecResult = mealy clk rstTest enableGen goFincFdec FInc counter + + -- Keep pressing FDEC, expect counter to go below -@threshold@ + goFdec :: Signed 32 -> (SpeedChange, TestState) + goFdec n + | n > threshold = (NoChange, Fail) + | n < -threshold = (NoChange, Success) + | otherwise = (SlowDown, Busy) + + -- Keep pressing FINC, expect counter to go above @threshold@ + goFinc :: Signed 32 -> (SpeedChange, TestState) + goFinc n + | n > threshold = (NoChange, Success) + | n < -threshold = (NoChange, Fail) + | otherwise = (SpeedUp, Busy) + + -- Keep pressing FDEC, expect counter to go below -@threshold@, then keep pressing + -- FINC, expect counter to go above 0. + goFdecFinc :: Test -> Signed 32 -> (Test, (SpeedChange, TestState)) + goFdecFinc FDec n + | n > threshold = (FDec, (NoChange, Fail)) + | n < -threshold = (FInc, (NoChange, Busy)) + | otherwise = (FDec, (SlowDown, Busy)) + goFdecFinc FInc n + | n > 0 = (FInc, (NoChange, Success)) + | n < -(3*threshold) = (FInc, (NoChange, Fail)) + | otherwise = (FInc, (SpeedUp, Busy)) + goFdecFinc s _ = (s, (NoChange, Fail)) -- Illegal state + + -- Keep pressing FINC, expect counter to go above @threshold@, then keep pressing + -- FDEC, expect counter to go below 0. + goFincFdec :: Test -> Signed 32 -> (Test, (SpeedChange, TestState)) + goFincFdec FInc n + | n > threshold = (FDec, (NoChange, Busy)) + | n < -threshold = (FInc, (NoChange, Fail)) + | otherwise = (FInc, (SpeedUp, Busy)) + goFincFdec FDec n + | n > (3 * threshold) = (FDec, (NoChange, Fail)) + | n < 0 = (FDec, (NoChange, Success)) + | otherwise = (FDec, (SlowDown, Busy)) + goFincFdec s _ = (s, (NoChange, Fail)) -- Illegal state + +fincFdecTests :: + -- Pins from internal oscillator: + "CLK_125MHZ" ::: DiffClock Basic125 -> + + -- Pins from clock board: + "USER_SMA_CLOCK" ::: DiffClock Basic200B -> + "MISO" ::: Signal Basic200A Bit -> -- SPI + + "" ::: + ( "" ::: + ( "done" ::: Signal Basic200A Bool + , "success" ::: Signal Basic200A Bool + ) + + -- Freq increase / freq decrease request to clock board + , "" ::: + ( "FINC" ::: Signal Basic200A Bool + , "FDEC" ::: Signal Basic200A Bool + ) + + -- SPI to clock board: + , "" ::: + ( "SCLK" ::: Signal Basic200A Bool + , "MOSI" ::: Signal Basic200A Bit + , "CSB" ::: Signal Basic200A Bool + ) + ) +fincFdecTests diffClk controlledDiffClock spiIn = + ((testDone, testSuccess), fIncDec, spiOut) + where + clkControlled = ibufds controlledDiffClock + + (clk, clkStable0) = clockWizardDifferential (SSymbol @"pll") diffClk noReset + clkStable1 = xpmCdcSingle clk clk clkStable0 -- improvised reset syncer + + clkStableRst = unsafeFromActiveLow clkStable1 + anyStarted = fold (||) <$> startTests + testRst = orReset clkStableRst (unsafeFromActiveLow anyStarted) + testRstBool = unsafeToActiveHigh testRst + + (fInc, fDec) = fIncDec + + testF = fst . findWithDefault (FDec, True) snd . zip allTests <$> startTests + + (testResult, fIncDec, spiOut, debugSignals) = + goFincFdecTests clk testRst clkControlled testF spiIn + + (testDone, testSuccess) = unbundle $ testStateToDoneSuccess <$> testResult + + (spiBusy, spiState, siClkLocked, counterActive, counter) = debugSignals + + startTests :: Signal Basic200A (Vec 4 Bool) + startTests = + vioProbe + ( "probe_test_done" + :> "probe_test_success" + + -- Debug signals: + :> "probe_clkStable1" + :> "probe_testRstBool" + :> "probe_spiBusy" + :> "probe_spiState" + :> "probe_siClkLocked" + :> "probe_counterActive" + :> "probe_counter" + :> "probe_fInc" + :> "probe_fDec" + :> Nil) + ( "probe_test_start_fdec" + :> "probe_test_start_finc" + :> "probe_test_start_fdecfinc" + :> "probe_test_start_fincfdec" + :> Nil) + (repeat False) + clk + testDone + testSuccess + + -- Debug signals + clkStable1 + testRstBool + spiBusy + spiState + siClkLocked + counterActive + counter + fInc + fDec +{-# NOINLINE fincFdecTests #-} +makeTopEntity 'fincFdecTests diff --git a/bittide/src/Bittide/ClockControl.hs b/bittide/src/Bittide/ClockControl.hs index 4b88350a0..895e0477c 100644 --- a/bittide/src/Bittide/ClockControl.hs +++ b/bittide/src/Bittide/ClockControl.hs @@ -4,7 +4,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE NamedFieldPuns #-} -{-# OPTIONS_GHC -Wno-orphans #-} +{-# OPTIONS_GHC -Wno-orphans -fconstraint-solver-iterations=10 #-} -- | Clock controller types and some constants/defaults. module Bittide.ClockControl @@ -16,6 +16,7 @@ module Bittide.ClockControl , pessimisticSettleCycles , targetDataCount , clockPeriodFs + , speedChangeToFincFdec ) where @@ -26,7 +27,7 @@ import Data.Proxy (Proxy(..)) import GHC.Stack (HasCallStack) import Bittide.Arithmetic.Ppm -import Bittide.Arithmetic.Time (microseconds) +import Bittide.Arithmetic.Time (PeriodToCycles, Nanoseconds, Microseconds, microseconds) import Data.Csv @@ -120,6 +121,46 @@ data SpeedChange | NoChange deriving (Eq, Show, Generic, ShowX, NFDataX) +data ToFincFdecState dom + = Wait (Index (PeriodToCycles dom (Microseconds 1))) + | Pulse (Index (PeriodToCycles dom (Nanoseconds 100))) SpeedChange + | Idle + deriving (Generic, NFDataX) + +-- | Convert 'SpeedChange' to a pair of (FINC, FDEC). This is currently hardcoded +-- to work on the Si5395 constraints: +-- +-- * Minimum Pulse Width: 100 ns +-- * Update Rate: 1 us +-- +-- TODO: De-hardcode +speedChangeToFincFdec :: + forall dom . + KnownDomain dom => + Clock dom -> + Reset dom -> + Signal dom SpeedChange -> + Signal dom (Bool, Bool) +speedChangeToFincFdec clk rst = + dflipflop clk . fmap conv . mealy clk rst enableGen go (Wait maxBound) + where + go :: ToFincFdecState dom -> SpeedChange -> (ToFincFdecState dom, SpeedChange) + go (Wait n) _s + | n == 0 = (Idle, NoChange) + | otherwise = (Wait (n - 1), NoChange) + + go (Pulse n s) _s + | n == 0 = (Wait maxBound, s) + | otherwise = (Pulse (n - 1) s, s) + + go Idle NoChange = (Idle, NoChange) + go Idle s = (Pulse maxBound s, NoChange) + + -- FINC FDEC + conv NoChange = (False, False) + conv SpeedUp = (True, False) + conv SlowDown = (False, True) + instance ToField SpeedChange where toField SpeedUp = "speedUp" toField SlowDown = "slowDown" diff --git a/bittide/src/Bittide/ClockControl/Si539xSpi.hs b/bittide/src/Bittide/ClockControl/Si539xSpi.hs index 5d8aa4709..cab7a26bd 100644 --- a/bittide/src/Bittide/ClockControl/Si539xSpi.hs +++ b/bittide/src/Bittide/ClockControl/Si539xSpi.hs @@ -1,12 +1,13 @@ -- SPDX-FileCopyrightText: 2022-2023 Google LLC -- -- SPDX-License-Identifier: Apache-2.0 -{-# OPTIONS_GHC -fconstraint-solver-iterations=9 #-} +{-# OPTIONS_GHC -fconstraint-solver-iterations=15 #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE NumericUnderscores #-} {-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE UndecidableInstances #-} module Bittide.ClockControl.Si539xSpi where @@ -103,6 +104,11 @@ data ConfigState dom entries -- ^ Waits for the Si539X to be calibrated after writing the configuration preamble from 'Si539xRegisterMap'. deriving (Show, Generic, NFDataX, Eq) +instance + ( 1 <= entries + , KnownNat (DomainPeriod dom) + , KnownNat entries ) => BitPack (ConfigState dom entries) + -- | Utility function to retrieve the entry 'Index' from the 'ConfigState'. getStateAddress :: KnownNat entries => ConfigState dom entries -> Index entries getStateAddress = \case