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
-
\$\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– Mr. Snrub2020年06月14日 20:22:51 +00:00Commented Jun 14, 2020 at 20:22
-
\$\begingroup\$ Thank you for your valuable input. I have added the entity code. \$\endgroup\$Sunkeerth Muppala– Sunkeerth Muppala2020年06月15日 10:24:06 +00:00Commented Jun 15, 2020 at 10:24
2 Answers 2
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.
-
\$\begingroup\$ Thanks for your input. Could you clarify what you meant in the last line \$\endgroup\$Sunkeerth Muppala– Sunkeerth Muppala2020年06月15日 10:25:58 +00:00Commented Jun 15, 2020 at 10:25
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.