1
\$\begingroup\$

I am trying to write code for a cyclic code encoder in VHDL, but I am not able to visualize how to approach the problem. Right now all I have is an entity and a few diagrams showing my approach as to how I want to build it. If anyone could help me out or point me in the right direction it would be really helpful.

Code for the entity I've written

-- generator matrix is 1 + D + D^3
-- g0 = 1
-- g1 = 1
-- g2 = 0
-- g3 = 1

library IEEE;  
use ieee.std_logic_1164.all;   
use ieee.std_logic_signed.all;   

 
 entity cc_7_4 is  
 generic (  
           n            : integer     :=7               ;-- CW length
           k            : integer     :=4               ;-- message length
           
 port(  
      message_input     : in  std_logic_vector(k-1 downto 0)                ;-- input data  
      clk               : in  std_logic                                     ;-- input clk  
      D                 : inout  std_logic_vector((n-k-1) downto 0):="000"  ;-- pipo shift register to generate the parity bits
      Q                 : inout std_logic_vector((n-k-1) downto 0)          ;-- pipo shift register to generate the parity bits
      rst               : in  std_logic                                     ;-- input reset  
      output            : out std_logic_vector(6 downto 0))                 ;-- output data  
 
 
 end cc_7_4;  

The cyclic encoder I'm trying to achieve

How I think I should proceed enter image description here

\$\endgroup\$
2
  • \$\begingroup\$ You say you "have an entity" -- what does the entity look like? What are the interfaces to this entity, in detail? Are your data inputs and outputs serial or parallel? What synchronization signals do you have to and from this entity? Specifying this in detail (including the required timing relationships) is a great first step in figuring out the solution to any digital design problem. \$\endgroup\$ – Mr. Snrub Jun 14 '20 at 20:22
  • \$\begingroup\$ Thank you for your valuable input. I have added the entity code. \$\endgroup\$ – Sunkeerth Muppala Jun 15 '20 at 10:24
0
\$\begingroup\$

You’ve actually done the hard part by drawing out your block diagram. It’s a good diagram and you’ve derived the equations that you need to perform. Unfortunately you seem to have got stuck on the implementation at the register level, so your second diagram is very incorrect, although i can see you’re thinking on the right lines as you’re showing a shift register.

What you need to implement for this application is a linear feedback shift register. I’m not going to dwell on whether your base design is right, I’m going to answer your question on how.

You need the take advantage of the fact that VHDL allows you to abstract from the hardware. If you use the right packages (ieee.numeric_std) then all you need to do is write a process containing your equations.

Something like this will work:

Q(0) <= m + Q(2)

Q(1) <= m + Q(0)

Q(2) <= Q(1)

Don’t forget the multiplexor you’ve got in your diagram. That’s implemented with an if statement.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for your input. Could you clarify what you meant in the last line \$\endgroup\$ – Sunkeerth Muppala Jun 15 '20 at 10:25
0
\$\begingroup\$

RTL Design:

library IEEE;  
use ieee.std_logic_1164.all;   
use ieee.numeric_std.all;
 
 entity cc_7_4 is           
 port(code_in     : in  std_logic_vector(3 downto 0); -- input code
      clk         : in  std_logic;                    -- input clk  
      reset       : in  std_logic;                    -- input synchronous reset  
      code_out    : out std_logic_vector(6 downto 0)); -- output code  
 end cc_7_4;  
 
 architecture rtl of cc_7_4 is
 signal     q   : std_logic_vector(2 downto 0) := (others => '0'); --linear feedback shift register (lfsr)
 signal   sReg  : std_logic_vector(2 downto 0) := (others => '0'); --serial shift register to shift the input code into the lfsr    
 signal cycle   : unsigned(2 downto 0) := (others => '0'); --signal to store value of the cycle 
 begin
   proc: process(clk) 
   begin
   if rising_edge(clk) then
     if reset = '1' then 
      code_out <= (others => '0');
      q     <= "000";  
      sReg  <= "000";
      cycle <= "000";
     elsif cycle = "000" then
        code_out(3 downto 0) <= code_in; 
        sReg <= code_in(3 downto 1);
        q(2) <= code_in(0) xor q(0);
        q(1) <= code_in(0) xor q(0) xor q(2);
        q(0) <= q(1); 
        cycle <= cycle + 1;
     elsif cycle <= "011" then
        sReg <= '0' & sReg(2 downto 1);
        q(2) <= sReg(0) xor q(0);
        q(1) <= sReg(0) xor q(0) xor q(2);
        q(0) <= q(1);
        cycle <= cycle + 1;
     elsif cycle = "100" then   
        code_out(6 downto 4) <= q;
        q     <= "000"; 
        cycle <= "000";
     end if;  
   end if; 
   end process proc;
 end architecture rtl;  

Output is produced on the 5th clock cycle, after 4 shifts.

Click here to simulate it in your browser, on EDA Playground.

Testbench:

library IEEE;
use IEEE.std_logic_1164.all;

entity tb is
end entity;

architecture simulate of tb is

component cc_7_4 is
  port(  
      code_in     : in  std_logic_vector(3 downto 0); -- input code
      clk         : in  std_logic;                    -- input clk  
      reset       : in  std_logic;                    -- input synchronous reset  
      code_out    : out std_logic_vector(6 downto 0));-- output code  
end component cc_7_4; 

 signal clk       :  std_logic:= '0'; 
 signal reset     :  std_logic:= '1'; 
 signal code_in   :  std_logic_vector(3 downto 0):= "0011";   
 signal code_out  :  std_logic_vector(6 downto 0):= "0000000";
 
begin 
  --instantiate the unit under test (UUT)
   uut: cc_7_4
        port map (
          clk         => clk,
          reset       => reset,
          code_in     => code_in,
          code_out    => code_out
       );
       
  --Clock Process     
  clock_proc: process begin
  clk <= '1'; wait for 5 ns;
  clk <= '0'; wait for 5 ns;
  end process clock_proc;

    --Stimulus Process
  stim_proc: process
  begin  
  wait until falling_edge(clk);
  reset <= '0';
  wait until falling_edge(clk);
  wait until falling_edge(clk);
  wait until falling_edge(clk);
  wait until falling_edge(clk);
  wait until falling_edge(clk);
  wait until falling_edge(clk);
  wait until falling_edge(clk);
  std.env.stop(0);
  end process stim_proc;
  
end architecture simulate;  

Waveform on simulating with the above testbench can be viewed by clicking here.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.