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.

14-bit shift register vhdl

Status
Not open for further replies.

jimmykk

Full Member level 3
Joined
Oct 2, 2014
Messages
158
Helped
0
Reputation
0
Reaction score
1
Trophy points
1,298
Activity points
2,863
Hi
i am writing code for shift register with serial out data. i am having some code problem, when i change the STEP to value other than 14398, i dont get any output. basically STEP increases with every clock and when it equals certain count, it should output data serially.
here is my code:-


Code Verilog - [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
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity light is
port(
CLOCK_50 : in std_logic;
reset : in std_logic;
enable : in std_logic;
GPIO_1 : inout std_logic_vector(35 downto 0);
GPIO_0 : out std_logic_vector(35 downto 0)
 
) ; 
end light;
 
 
 
architecture logicfunction of light is
type state_type is (wait_state,shift_state);
SIGNAL present_state : state_type;
signal turn    : std_logic := '0';
signal RISINGEDGE     : std_logic := '1';
signal count : integer range 0 to 10 :=0;  -- register that keeps the count
signal data : std_logic := '0';
signal shift_reg : std_logic_vector(13 downto 0) := (Others => '0'); 
--signal dac_cnt_half : std_logic_vector(13 downto 0)   := "01110000011111";
signal dac_cnt_max : std_logic_vector(13 downto 0)      := "11100000111110";
begin
 
GPIO_1(1) <= turn;
clk_div: process(CLOCK_50)
 
begin
if (rising_edge(CLOCK_50)) then
 
if(count = 10) then    --*
turn <= turn XOR '1';
RISINGEDGE <= RISINGEDGE XOR '1';
count <= 0;
else
count <= count + 1;
end if;
end if;
end process clk_div;
 
 
 
MAIN: process(turn,reset)
variable shift_counter : integer := 0;
variable step : integer range 0 to 100000 := 0;
begin
if (reset = '1') then
shift_reg <= (others => '0');
present_state <= wait_state;
shift_counter := 0;
 
elsif(turn'event and turn = '1') then
 
case present_state is
 
when wait_state =>
shift_counter := 0;
shift_reg <= dac_cnt_max;  
GPIO_1(2) <= '0';
 
if (step = 14398) then
step := 0;
present_state <= shift_state;
else
step := step + 1;
present_state <= wait_state;
end if;
 
 
when shift_state =>
shift_counter := shift_counter + 1;
GPIO_1(2) <= shift_reg(0);
shift_reg <= data & shift_reg(13 downto 1);
if (shift_counter >= 13) then
present_state <= wait_state;
else 
present_state <= shift_state;
end if;
end case;
end if; 
end process MAIN;
end logicfunction;



Anybody which can explain and help me where i am doing wrong
 
Last edited by a moderator:

Why are you generating a turn clock, turn should be an enable signal and the MAIN process should be run off the CLOCK_50. Generating clocks in an FPGA's fabric is not advised, due to problems in routing the clock from logic resources.

I'm not a VHDL expert, but I wonder if the problem has to do with using variables for shift_counter and step. I don't see why you can't use a signal for either of those counters. Unless you really know what hardware a variable will describe I would avoid them altogether.

As a suggestion I would not use = for comparing counter terminal values. If the counter accidentally ends up with a count value beyond the terminal value it will continue counting till it rolls over.
 

First question - where is your testbench?
Second - like ads-ee - why are you generating clocks?

I also advise you use only signals, no variables. There is nothing you can do with a variable you can do with a signal (and you're safer using a signal).
 

ok....i got this that i need to synchronize my processes with the same system clock , so i will use just one clock and divide to to the desired range and use step and shift_counter as signals. but my main problem is that i want to get a specific voltage out (between 0 and 3.3V) whenever step equals a particular count and i want that count as output voltage like for 14398, the output voltage should be 2.9 V and for step =12412, voltage should be 2.5V, IF this makes sense.
 

Doesnt really make sense as I have no idea what component you are using.
The easiest thing for you would be to make a testbench, so that with a known set of inputs and outputs, you can check your design is working correctly.
 

i am using a 14-bit spi dac AD5641 acting as a shift register to get analog voltage
 

Using divided clocks is bad design practice, as said, but it doesn't cause problems for an isolated entity that doesn't interface with other design units as long as the divided clock is a glitch-free registered signal.

To work as a SPI master, your design should be supplemented with a slave select ("SYNC") signal, operated according to AD5641 specification.

I don't a reason why the step won't work for arbitrary delays up to the number range. Although using signals for the counter would be the regular VHDL way, variables do work in this specific case. A possible disadvantage can be seen in the below snippet where the comparison refers to the updated value shift_counter + 1 which possibly creates more complex logic than required for a signal due to the "blocking" behaviour of variable assignments. This can cause timing issues in real complex logic designs.

Code:
shift_counter := shift_counter + 1;
GPIO_1(2) <= shift_reg(0);
shift_reg <= data & shift_reg(13 downto 1);
if (shift_counter >= 13) then
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top