Advertisement
Guest User

Untitled

a guest
Jun 8th, 2025
20
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /////////////////////////////////////////////////////////////////////////////////
  2. //{{{ BSD 3-Clause License
  3. // Copyright 2024
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are met:
  7. //
  8. // 1. Redistributions of source code must retain the above copyright notice,
  9. //    this list of conditions and the following disclaimer.
  10. //
  11. // 2. Redistributions in binary form must reproduce the above copyright notice,
  12. //    this list of conditions and the following disclaimer in the documentation
  13. //    and/or other materials provided with the distribution.
  14. //
  15. // 3. Neither the name of the copyright holder nor the names of its
  16. //    contributors may be used to endorse or promote products derived from this
  17. //    software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
  20. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  23. // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  24. // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  25. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  27. // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  28. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  29. // POSSIBILITY OF SUCH DAMAGE.
  30. //}}}
  31. `default_nettype none
  32.  
  33. ////////////////////////////////////////////////////////////////////////////////
  34. // {{{ lfsr_io_check commentary:
  35. // lfsr sequence checker for IO.  This is a fancy version of lfsr_check.
  36. // this version makes a state vector from the lsb of the input.  This means
  37. // the checker takes pStateWidth inputs to load the state, independent of
  38. // pBusWidth.
  39. //
  40. // this method has the benefit that errors specific to IO are easier to
  41. // detect.  if the lsb of the bus is fine, then this version will be able to
  42. // check the other bits without those errors affecting the other lines.
  43. // This method also generates early/late checks for everything but the lsb.
  44. //
  45. // The early/late checks can have 1's, but having more than pStateWidth in a row
  46. // is an error.
  47. //
  48. // To be an effective IO checker, pBusWidth should be coprime with
  49. // (2**pStateWidth - 1).  otherwise, some bits will have shorter sequence
  50. // lengths.
  51. // }}}
  52.  
  53. ////////////////////////////////////////////////////////////////////////////////
  54. // {{{ Module
  55. module lfsr_io_check #(
  56.     parameter pStateWidth = 17,
  57.     parameter pBusWidth = 8,
  58.     parameter pSerdes = 1,
  59.     parameter [pStateWidth-1:0] pTaps = 17'b1_0010_0000_0000_0000
  60. ) (
  61.     output reg [pBusWidth-1:0] oErr,
  62.     output reg [pBusWidth-1:0] oEarly,
  63.     output reg [pBusWidth-1:0] oLate,
  64.     input wire [pSerdes*pBusWidth-1:0] iData,
  65.     input wire iEn,
  66.     input wire clk,
  67.     input wire rst
  68. );
  69. //}}}
  70.  
  71.     ////////////////////////////////////////////////////////////////////////////
  72.     // {{{ re-declare
  73.     localparam S = pStateWidth;
  74.     localparam B = pBusWidth;
  75.     localparam N = pSerdes * pBusWidth;
  76.     localparam T = pTaps;
  77.     //}}}
  78.  
  79.     ////////////////////////////////////////////////////////////////////////////
  80.     // {{{ matrix solver function
  81.     // early[N-1][S-1:0] .. late[N-1][S-1:0] .. expected[N-1][S-1:0]
  82.     function automatic [(B+B+N)*S-1:0] solver(input unused); begin : decl
  83.         reg [S-1:0] state;
  84.         reg [S-1:0] col;
  85.         reg [N-1:0] late;
  86.         integer i;
  87.         integer j;
  88.         reg [B+B+N+S-1:0] mtx [0:S-1]; // early, late, expected, state
  89.         localparam kState0 = 0;
  90.         localparam kStateEnd = kState0 + S - 1;
  91.         localparam kBus0 = (kStateEnd+1);
  92.         localparam kBusEnd = kBus0 + N - 1;
  93.         localparam kLate0 = kBusEnd + 1;
  94.         localparam kLateEnd = kLate0 + B - 1;
  95.         localparam kEarly0 = kLateEnd + 1;
  96.         localparam kEarlyEnd = kEarly0 + B - 1;
  97.  
  98.         // initialize serial state
  99.         // V       | the right column will be the state for the checker
  100.         // 1 2 3 4 | this first step gets every N'th bit from the lfsr
  101.         // 5 6 7 8 | output.
  102.         // 9 A B C |
  103.         // D E F 1.| col = 4 8 C 1.  msb=4, lsb=1
  104.         state = {(S){1'b1}};
  105.         for (i = 0; i < N*S; i = i + 1) begin
  106.             state = (state << 1) ^ (^(state & T));
  107.             if (i % N == N-1) begin
  108.                 col = (col << 1) ^ state[0];
  109.             end
  110.             late = (late << 1) ^ state[0];
  111.         end
  112.  
  113.         // form main matrix:
  114.         //  N+S columns
  115.         //  N+S-1          S   S-1                0
  116.         //  first       last
  117.         // [outMsb .. outLsb] [stateMsb .. stateLsb]
  118.         //         ...      S rows      ...
  119.         //
  120.         //  each row has the outputs to be generated from the state.
  121.         //  the next row's state is based on a shift + one of those bits.
  122.         for (j = 0; j < S; j = j + 1) begin
  123.             mtx[j][kStateEnd:kState0] = col;
  124.             for (i = 0; i < N; i = i + 1) begin
  125.                 state = (state << 1) ^ (^(state & T));
  126.                 mtx[j][kBusEnd-i] = state[0];
  127.             end
  128.             col = (col << 1) ^ mtx[j][S];
  129.         end
  130.  
  131.         // fill in early/late
  132.         // c d e f g -- early
  133.         // b c d e f -- expected
  134.         // a b c d e -- late
  135.         mtx[0][kLate0+:B] = (pSerdes==1) ? late : mtx[0][kBus0+B+:B];
  136.         mtx[0][kEarly0+:B] = mtx[1][kBusEnd-:B];
  137.         for (i = 1; i < S-1; i = i + 1) begin
  138.             mtx[i][kLate0+:B] = (pSerdes==1) ? mtx[i-1][kBus0+:B] : mtx[i][kBus0+B+:B];
  139.             mtx[i][kEarly0+:B] = mtx[i+1][kBusEnd-:B];
  140.         end
  141.         mtx[S-1][kLate0+:B] = (pSerdes==1) ? mtx[S-1-1][kBus0+:B] : mtx[S-1][kBus0+B+:B];
  142.         for (i = 0; i < B; i = i + 1) begin
  143.             state = (state << 1) ^ (^(state & T));
  144.             mtx[S-1][kEarlyEnd-i] = state[0];
  145.         end
  146.  
  147.         // triangular
  148.         // [ bits ] [? ? ... ? 1]
  149.         // [ bits ] [? ? ... 1 0]
  150.         //         ...
  151.         // [ bits ] [? 1 ... 0 0]
  152.         // [ bits ] [1 0 ... 0 0]
  153.         for (j = 0; j < S; j = j + 1) begin
  154.             if (!mtx[j][j]) begin
  155.                 i = j;
  156.                 while (i < S && !mtx[i][j]) begin
  157.                     i = i + 1;
  158.                 end
  159.                 mtx[j] = mtx[j] ^ mtx[i];
  160.             end
  161.             for (i = j+1; i < S; i = i + 1) begin
  162.                 if (mtx[i][j]) begin
  163.                     mtx[i] = mtx[i] ^ mtx[j];
  164.                 end
  165.             end
  166.         end
  167.  
  168.         // diagonal
  169.         // [ out(N-1)tap(0)   ...   out(0)tap(0)] [0 0 ... 0 1]
  170.         // [ out(N-1)tap(1)   ...   out(0)tap(1)] [0 0 ... 1 0]
  171.         //                                      ...
  172.         // [ out(N-1)tap(S-2) ... out(0)tap(S-2)] [0 1 ... 0 0]
  173.         // [ out(N-1)tap(S-1) ... out(0)tap(S-1)] [1 0 ... 0 0]
  174.         for (j = S-1; j > 0; j = j - 1) begin
  175.             for (i = 0; i < j; i = i + 1) begin
  176.                 if (mtx[i][j]) begin
  177.                     mtx[i] = mtx[i] ^ mtx[j];
  178.                 end
  179.             end
  180.         end
  181.  
  182.         // results:
  183.         // {out(N-1)[S-1:0] ... out(0)[S-1:]}
  184.         for (j = 0; j < B+B+N; j = j + 1) begin
  185.             for (i = 0; i < S; i = i + 1) begin
  186.                 solver[S*j + i] = mtx[i][kBus0+j];
  187.             end
  188.         end
  189.     end endfunction
  190.     //}}}
  191.  
  192.     ////////////////////////////////////////////////////////////////////////////
  193.     // {{{ next-value logic
  194.     reg [S-1:0] state;
  195.     reg [N-1:0] error_bits;
  196.     reg [B-1:0] early_match;
  197.     reg [B-1:0] late_match;
  198.     reg [B-1:0] error_lanes;
  199.     integer i;
  200.     localparam [(B+B+N)*S-1:0] kMtx = solver(0);
  201.     localparam kPredict0 = 0;
  202.     localparam kPredictEnd = kPredict0 + N - 1;
  203.     localparam kLate0 = kPredictEnd + 1;
  204.     localparam kLateEnd = kLate0 + B - 1;
  205.     localparam kEarly0 = kLateEnd + 1;
  206.     localparam kEarlyEnd = kEarly0 + B - 1;
  207.  
  208.     always@(*) begin
  209.         for (i = 0; i < N; i = i + 1) begin
  210.             error_bits[i] = ^(state & kMtx[(kPredict0 + i)*S+:S]) ^ iData[i];
  211.         end
  212.         for (i = 0; i < B; i = i + 1) begin
  213.             early_match[i] = ^(state & kMtx[(kEarly0 + i)*S+:S]) ^ ~iData[i];
  214.             late_match[i] = ^(state & kMtx[(kLate0 + i)*S+:S]) ^ ~iData[i];
  215.         end
  216.         error_lanes = 0;
  217.         for (i = 0; i < pSerdes; i = i + 1) begin
  218.             error_lanes = error_lanes | error_bits[B*i+:B];
  219.         end
  220.     end
  221.     //}}}
  222.  
  223.     ////////////////////////////////////////////////////////////////////////////
  224.     // {{{ state and output registers
  225.     always@(posedge clk) begin
  226.         if (iEn) begin
  227.             oErr <= error_lanes;
  228.             oEarly <= early_match;
  229.             oLate <= late_match;
  230.             state <= {state[S-2:0], iData[0]};
  231.         end
  232.         if (rst) begin
  233.             state <= 1;
  234.         end
  235.     end
  236.     //}}}
  237.  
  238. endmodule
  239. `default_nettype wire
  240.  
  241.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement