Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Serial Receiver & transmitter in VHDL

Status
Not open for further replies.

Morell

Member level 1
Joined
Dec 1, 2015
Messages
35
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
614
Hi,

-I wrote some codes for these modules(Serial receiver & transmitter).
-Both were synthesized and implemented on Spartan-3 and they worked correctly.
-I want to use them as components in another module so i need the codes to be more modular than now.

This is the Receiver :

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
entity Receiver is
    Port ( Clk : in std_logic;
           RxD : in std_logic;
           Parallel_out : out std_logic_vector(7 downto 0));
end Receiver;
 
architecture Behavioral of Receiver is
    Signal CTR : Std_logic_vector (15 downto 0) := X"0AAA";
    Type State is (idle,Receive);
    Signal CS : state := idle;
    Signal Data : Std_logic_vector (8 downto 0);
begin
Parallel_out <= Data(8 downto 1);
Process (Clk)
    Variable i : integer Range 10 downto 0 := 0;
Begin 
if(Clk'event and Clk = '1') then
    Case CS is 
        When idle =>
            if (RxD = '0') then 
                CS <= Receive;
            else 
                null;
            end if;
        When Receive =>
            CTR <= CTR + X"0001";
            if (CTR = X"1555") then 
                if (i < 9) then
                    Data (i) <= RxD;
                    i := i +1;
                    CTR <= X"0000";
                else 
                    CS <= Idle;
                    CTR <= X"0AAA";
                    i := 0;
                end if;
            end if;
end case;
end if;                     
end process;                 
    
end Behavioral;






and this is the transmitter :


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
entity Transmitter is
    Port ( CLK : in std_logic;
           ENTER : in std_logic;
           TXD : out std_logic;
           DATA : in std_logic_vector(7 downto 0);
           LED : out std_logic_vector(7 downto 0));
end Transmitter;
 
architecture Behavioral of Transmitter is
 
 
    signal CTR : std_logic_vector (15 downto 0) := X"0000";
    Signal Sot : std_logic := '0';   -- Start of Transmission 
    Signal En1 : std_logic := '0';   -- Flag 
    Signal En2 : std_logic := '0';   -- Flag
 
    type state is (idle , transmission);
 
    signal send : std_logic_vector (9 downto 0);
begin
    LED <= DATA;
    Send <= '1' & DATA & '0';
process (CLK)
variable i :integer range 10 downto 0 := 0 ;
begin 
    if (CLK'event and CLK='1') then 
    CTR <= CTR + "0001";
 
 
    En1 <= Enter;
    En2 <= En1;
 
                 
    if (EN1 = '1' AND EN2 = '1') then 
        Sot <= '1';
    end if;
    
    
    if (Sot = '1') then         
        if (CTR = X"1458") then 
            if (i < 10) then 
                TxD <= Send (i);
                i := i + 1;
                CTR <= X"0000";
            else 
                i := 0;
                CTR <= X"0000";
                SOT <= '0';
            end if;
        end if;
    end if;
end if;
end process;
end Behavioral;



Thanks alot
 

What exactly do you want to do with them? whats wrong with them as they are? Whats stopping you using these in another design?
 
  • Like
Reactions: Morell

    Morell

    Points: 2
    Helpful Answer Positive Rating
Hi,

-I wrote some codes for these modules(Serial receiver & transmitter).
-Both were synthesized and implemented on Spartan-3 and they worked correctly.
-I want to use them as components in another module so i need the codes to be more modular than now.

Adding a parameter to define the clock period and another one to define the communication rate would be a good start. Beyond that, well you haven't asked any question here so good luck.

Kevin Jennings
 
  • Like
Reactions: Morell

    Morell

    Points: 2
    Helpful Answer Positive Rating
1- After implementing on the board, I assign "Enter" to a push button on the board and
when I push the "Enter" button, This module will send 2 bytes, sometimes 3 bytes sometimes more,
My teacher told me something about a topic called "Debouncing" and that i have to design a "software debouncer ".
I want to remove this bounce from this button.

2- When I use these modules as a component, They do not work correctly.
The Transmitter doesn't work at all

This is the top module :


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
entity ET_1 is
    Generic (: integer range 0 to 10 :=4;-- K bits for Message
                 N  : integer range 0 to 20 :=7);-- N bits for Codeword 
    
    Port     (Message : in std_logic_vector ( (K-1) downto 0);
                 Codeword_serial : out std_logic;
                 Start : in std_logic;
                 LED : out std_logic_vector (7 downto 0);
                 Clock : in std_logic;
                 Reset : in std_logic);
    
end ET_1;
 
architecture Behavioral of ET_1 is
 
--========================================================================
-- Component Declaration 
-- 1st 
 
Component Encode
 
    Generic (: integer range 0 to 10 :=4;-- K bits for Message
                 N  : integer range 0 to 20 :=7);-- N bits for Codeword 
                 
    Port        (Clock : in STD_LOGIC;
                 ReSeT : in STD_LOGIC;
                 
                 Val_in : in STD_LOGIC;
                 Val_out : out STD_LOGIC;
                 
                 U : in STD_LOGIC_VECTOR((K-1) downto 0);
                 V : out STD_LOGIC_VECTOR((N-1) downto 0));
                 
end Component;
 
-- 2nd
 
Component Transmitter 
    Port ( CLK : in std_logic;
           ENTER : in std_logic;
           TXD : out std_logic;
           DATA : in std_logic_vector(7 downto 0);
           LED : out std_logic_vector(7 downto 0));
end Component;
--========================================================================
--Signal Declaration 
Signal U_Reg : std_logic_vector ((K-1) downto 0):=(Others =>'0');
Signal Start_Reg : std_logic := '0';
 
Signal V_Reg,V_Wire : std_logic_vector ((N-1) downto 0):=(Others =>'0');
Signal Encode_Finished_Wire,Encode_Finished_Reg : std_logic :='0';
Signal DATA : std_logic_Vector (7 downto 0):=(Others => '0');
 
Signal LED_out : std_logic_vector(7 downto 0):=(Others => '0');
--========================================================================
 
begin
 
Unit1: Encode       Port Map (Clock,Reset,Start_Reg,Encode_Finished_wire,U_Reg,V_wire);
 
Unit2: Transmitter Port Map (Clock,Encode_Finished_Reg,Codeword_Serial,DATA,LED_out);
 
LED <= LED_out;
 
DATA <= '0' & V_Reg;
 
Process(Clock)
begin 
    if rising_edge(Clock) then 
        
        U_Reg <= Message;
        Start_Reg <= Start;
        Encode_Finished_Reg <= Encode_Finished_Wire;
        V_Reg <= V_Wire;
        
        
    end if;
end Process;
end Behavioral;



This is the Encode Component:


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
entity Encode is
 
    Generic (: integer range 0 to 10 :=4;-- K bits for Message
                 N  : integer range 0 to 20 :=7);-- N bits for Codeword 
                 
    Port        (Clock : in STD_LOGIC;
                 ReSeT : in STD_LOGIC;
                 
                 Val_in : in STD_LOGIC;
                 Val_out : out STD_LOGIC;
                 
                 U : in STD_LOGIC_VECTOR((K-1) downto 0);
                 V : out STD_LOGIC_VECTOR((N-1) downto 0));
                 
end Encode;
 
architecture Behavioral of Encode is
 
--Component Declaration
Component Encoder 
    Generic (: integer range 0 to 10 :=4;-- K bits for Message
                 N  : integer range 0 to 20 :=7);-- N bits for Codeword      
    Port ( Data_in : in STD_LOGIC;
              Data_out : out STD_LOGIC;
              
           Clk : in  STD_LOGIC;
              Rst : in STD_LOGIC;
              
              Valid_in : in STD_LOGIC;
              Valid_out : out STD_LOGIC);
end Component;
 
--Signal Declaration 
Signal Utemp : STD_LOGIC_VECTOR((K-1) downto 0);
Signal Vtemp : STD_LOGIC_VECTOR((N-1) downto 0);
 
Signal Val_in_Reg : STD_LOGIC;
Signal Val_out_Wire : STD_LOGIC;
 
Signal i : integer range 0 to K := 0;
Signal j : integer range 0 to N := 0;
 
Signal Serial_U_in : STD_LOGIC;
Signal Serial_V_out : STD_LOGIC;
 
begin
----------------------------------------------------
--Component Instatiation
    Unit : Encoder        Port Map (Data_in => Serial_U_in,
                                            Data_out => Serial_V_out,
                                            Clk => clock,
                                            rst => reset,
                                            Valid_in => Val_in_Reg,
                                            Valid_out => Val_out_wire);
-----------------------------------------------------
--Other Combinatorial parts
    V <= Vtemp;
    --Val_out <= Val_out_Wire When j = N-1 else '0';
    
     
    Serial_U_in <= Utemp(i);
    
 
Process(Clock)
Begin 
    if rising_edge(Clock) then 
        if reset = '1' then 
            -- reset all assigned signals
            i <= 0;
            j <= 0;
            Val_in_Reg <= '0';
            Utemp <= (Others => '0');
            Vtemp <= (Others => '0');
        else
            -- default assignments
            Val_in_Reg <= Val_in;
            Utemp <= U;
            
            if (J = N-1) then 
                Val_out <= Val_out_Wire;
            end if;
            
            if( i < K - 1 and Val_in_Reg = '1') then 
                i <= i + 1;
            end if;
        --      Serial_U_in <= Utemp(i);
        --  elsif (i = K - 1) then 
        --      Serial_U_in <= Utemp(i);
        --  end if;
            
            if (Val_out_Wire = '1') then 
                VTemp(j) <= Serial_V_out;
                if(j < N-1) then
                    j <= j + 1;
                end if;
            end if;
            
        end if;
    end if;
end Process;
end Behavioral;



and this is the "encoder" that is used inside the "encode"


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
entity Encoder is
    Generic (: integer range 0 to 10 :=4;-- K bits for Message
                 N  : integer range 0 to 20 :=7);-- N bits for Codeword 
             
    Port ( 
              Data_in : in STD_LOGIC;
              Data_out : out STD_LOGIC;
              
                     Clk : in  STD_LOGIC;
              Rst : in STD_LOGIC;
              
              Valid_in : in STD_LOGIC;
              Valid_out : out STD_LOGIC);
end Encoder;
 
architecture Behavioral of Encoder is
 
--Constant Declaration
Constant GP : STD_LOGIC_VECTOR ((N-K) downto 0) :="1011";   -- Generator Polynomial of (N-K) Degree
 
--Signal Declaration
Signal D,Q : STD_LOGIC_VECTOR ((N-K-1) downto 0) :=(Others => '0'); -- Flip flop's Inputs
Signal ClockCounter : integer range 0 to N;
Signal GTemp,UQX : STD_LOGIC;
Signal Data_in_Reg,Valid_in_Reg : STD_LOGIC;
 
 
 
Type Sw is ( Parity , message );
Signal Switch : Sw := Message;
 
begin
 
--Combinatorial Part
    
--1)- taking care of FF's Input and XORs
--***CHECKED***
    Gen1:for i in 1 to N-K-1 generate 
        D(i) <= (Gtemp xor Q(i-1)) when GP(i)='1' else
                     Q(i-1);
    end generate;
    D(0) <= Gtemp;
------------------------------------------------------------------------------------------- 
 
--2) taking care of FF's Outputs
--***CHECKED***
    UQX <= (Data_in_Reg xor Q(N-K-1)) When (Valid_in_Reg = '1') else '0';
--------------------------------------------------------------------------------------------
    
--3) taking care of GATE
--***CHECKED*** 
    Gtemp <= UQX when Switch = Message else '0'; -- Gtemp <= UQX and Switch2
--------------------------------------------------------------------------------------------
 
-- taking care of Switch 2
--4)***CHECKED***
    Data_out <= Data_in_Reg When Switch = Message else Q(N-K-1);
--------------------------------------------------------------------------------------------
    Valid_out <= '0' When ClockCounter = N else Valid_in_Reg;
-- Sequential part Va
 
Process(Clk)
begin
    if rising_edge(clk) then 
    
        if Rst='1' then 
    
            -- reset all assigned signals here
            Q <= (Others => '0');
            ClockCounter <= 0;
            Data_in_Reg <= '0';
            Valid_in_Reg <= '0';
            Switch <= Message;
            
        else
            -- Default assignments first
            Q <= D;
            Valid_in_Reg <= Valid_in;
            Data_in_Reg <= Data_in;
            
            if Valid_in_Reg ='1' then 
                if ClockCounter < N then
                    ClockCounter <= ClockCounter + 1;
                end if;
            end if; 
            
            if ClockCounter = K-1 then 
                Switch <= Parity;
            end if;
                
        end if;--Reset
    end if;--Clock
end Process;
end Behavioral;



They all worked seperately on the board,
but together, They dont.
So I think this has to do something with "Modularity",
and that my code is not "Modular" enough.

- I need to know that why they do not work together.
- And how can I fix this?

Thanks alot my friend
 

It's probably missing or incorrect coordination rather than a "modularity problem".

There are some features that should be supplemented for the original receiver and transmitter component:
- a receive_valid signal, telling that a new serial frame has been decoded
- a transmitter_busy or _ready signal, telling when new data can be sent
- an input register for the transmitter unit

The general way to check why the code isn't working as expected is to write a test bench and "run" the design in a simulator.

I guess, the problems can be also seen by reviewing the code, but I confess I'm not too motivated to dig through it, the lastest when I see component instantiations with positional association and similar hard readable stuff.
 
  • Like
Reactions: Morell

    Morell

    Points: 2
    Helpful Answer Positive Rating
Thanks alot for your response!!
That is exactly what I am looking for.
I will write the new transmitter with your advises and tips.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top