In this blog we would be implementing a 3-bit palindrome sequence detector in Verilog. The problem is quite straightforward where we need to detect a 3-bit palindrome sequence from a continuous stream of single bit inputs.

Fig: Top level Block

There are different ways this problem can be looked into and one of them could be to use a finite state machine to detect input patterns of 000, 010, 101 and 111. However, the state machine can get a bit complex and you may end up missing an arc which may cause your logic to not work as intended. Instead we can solve this using a 2-bit shift register, a counter and a comparator.

The 2-bit shift register would be used to hold the last two bits seen in the sequence and the counter would only be used to ensure the logic works when the circuit has seen at least three bits since the last time it was reset. Once we have the counters and shift registers working, we would just need to compare bit[1] of the shift register with the incoming bit (x_i) and assert the palindrome output if they match.

Here is the verilog code which implements the above logic:

module palindrome3b (
  input   wire        clk,
  input   wire        reset,

  input   wire        x_i,

  output  wire        palindrome_o

  // --------------------------------------------------------
  // Internal wires
  // --------------------------------------------------------
  // 2-bit counter
  logic [1:0] cnt_q;
  logic [1:0] nxt_cnt;
  // 2-bit shift register
  logic [1:0] bits_seen;
  logic [1:0] nxt_bits;

  // Flops for counter and shift register
  always @(posedge clk or posedge reset)
    if (reset) begin
      cnt_q[1:0]      <= 2'h0;
      bits_seen[1:0]  <= 2'h0;
    end else begin
      cnt_q[1:0]      <= nxt_cnt[1:0];
      bits_seen[1:0]  <= nxt_bits[1:0];

  // Next counter logic
  assign nxt_cnt[1:0]  = cnt_q[1] ? cnt_q[1:0] : cnt_q[1:0] + 2'b01;
  // Next shift register logic
  assign nxt_bits[1:0] = {bits_seen[0], x_i};

  // Palindrome comparator
  assign palindrome_o  = cnt_q[1] & (bits_seen[1] == x_i);