I am trying to retrieve data from an array of records constant. This is what i have in my current implementation:
CONSTANT Total_Feeds : INTEGER := 12;
TYPE Feed IS RECORD
s_Divisor : INTEGER RANGE 0 TO 255;
Display_Text : STRING(1 TO 8);
END RECORD Feed;
TYPE Feed_Array IS ARRAY (0 TO Total_Feeds -1) OF Feed;
CONSTANT FEED_INFO : Feed_Array := (
(225,"""0.02mm"""),
(112,"""0.04mm"""),
(75,"""0.06mm"""),
(56,"""0.08mm"""),
(45,"""0.10mm"""),
(38,"""0.12mm"""),
(32,"""0.14mm"""),
(28,"""0.16mm"""),
(25,"""0.18mm"""),
(23,"""0.20mm"""),
(20,"""0.22mm"""),
(19,"""0.24mm""")
);
------lower section of menu fsm----------
process(clk, reset)
begin
if (reset = '1') then
menu_pr <= start;
feed_index_pr <= 2;
ks_divisor_pr <= 0;
elsif (rising_edge(clk)) then
menu_pr <= menu_nx;
feed_index_pr <= feed_index_nx;
ks_divisor_pr <= ks_divisor_nx;
end if;
end process;
------upper section of menu fsm----------
process (menu_pr, menu_on_flag, delayed_select, delayed_up,
delayed_down, delayed_left, feed_index_pr, thread_index_pr,
delayed_right, menu_left_flag, menu_right_flag, menu_up_flag, menu_down_flag)
variable feedindex : integer range 0 to total_feeds;
begin
case menu_pr is
when start =>
feedindex := feed_index_pr;
feed_index_nx <= feedindex;
ks_divisor_nx <= FEED_INFO(feedindex).s_Divisor;
menu_nx <= feed_left;
when feed_left =>
feedindex := feed_index_pr;
feed_index_nx <= feedindex;
ks_divisor_nx <= FEED_INFO(feedindex).s_Divisor;
if (menu_on_flag = '1' and delayed_right = '1' and menu_right_flag = '1') then
menu_nx <= feed_left_right;
else
menu_nx <= feed_left;
end if;
when feed_left_right =>
feedindex := feed_index_pr + 1;
if (feedindex > (Total_Feeds - 1)) then
feedindex := 0;
feed_index_nx <= feedindex;
ks_divisor_nx <= FEED_INFO(feedindex).s_Divisor;
menu_nx <= feed_left;
else
feed_index_nx <= feedindex;
ks_divisor_nx <= FEED_INFO(feedindex).s_Divisor;
menu_nx <= feed_left;
end if;
end case;
end process;
rate_out <=ks_divisor_pr;
States are added after successful verification with simulation.
I'm trying to get the s_divisor for each record from a process using the following command:
ks_divisor_nx <= FEED_INFO(feedindex).s_Divisor;
Where feedindex changes from 0 to Total_Feeds -1, and ks_divisor is integer range 0 to 255.
Simulation results show correct output for all assignments except for the records with index 0, 1, and 2. Simulation output shows values: 11, 48, and 33 respectively.
simulation results
Any help is greatly appreciated.
Thanks.
Related
Good time to everyone.
Resently I try to improve code in new project and found some interesting decoder.
It has 2 processes: in first all data formed and in second all bus triggered in out registers by control signal. But some wires need to be reset in some period of time (in second process).
So I deside to write this code for correct resettind some signals ([cm_regA/cm_regB] are records with different types of data):
----------------------------------------
LOAD_DATA_PROCESS: process(clk_i)
begin
if rising_edge(clk_i) then
if (reset_reg) then
cm_regB.reg_1 <= '0';
cm_regB.reg_2 <= '0';
cm_regB.reg_3 <= '0';
cm_regB.reg_4 <= '0';
else
if (load_reg) then
cm_regB <= cm_regA;
else null;
end if;
end if;
end if;
end process;
----------------------------------------
But this construction Synthesized with lot of multiplexers betwen reg_5...reg_10, so next code give me good synthesized construction and great speed:
----------------------------------------
LOAD_DATA_PROCESS: process(clk_i)
begin
if rising_edge(clk_i) then
if (reset_reg) then
cm_regB.reg_1 <= '0';
cm_regB.reg_2 <= '0';
cm_regB.reg_3 <= '0';
cm_regB.reg_4 <= '0';
else
if (load_reg) then
cm_regB.reg_1 <= cm_regA.reg_1;
cm_regB.reg_2 <= cm_regA.reg_2;
cm_regB.reg_3 <= cm_regA.reg_3;
cm_regB.reg_4 <= cm_regA.reg_4;
else null;
end if;
end if;
if (load_reg) then
cm_regB.reg_5 <= cm_regA.reg_5;
cm_regB.reg_6 <= cm_regA.reg_6;
cm_regB.reg_7 <= cm_regA.reg_7;
cm_regB.reg_8 <= cm_regA.reg_8;
cm_regB.reg_9 <= cm_regA.reg_9;
cm_regB.reg_10 <= cm_regA.reg_10;
else null;
end if;
end if;
end process;
----------------------------------------
So the questions next:
How make this construction more compact (like first example)?
Or how to make any changes in buses [cm_regA/cm_regB] visible for second example (in case changing first process and forgot add this changes to LOAD_DATA_PROCESS)?
P.S. Type of cm_regA and cm_regB are declarated in package. Here it is:
----------------------------------------
type cm_t is record
reg_1 : STD_LOGIC;
reg_2 : STD_LOGIC;
reg_3 : STD_LOGIC;
reg_4 : STD_LOGIC;
reg_5 : STD_LOGIC;
reg_6 : BOOLEAN;
reg_7 : STD_LOGIC;
reg_8 : STD_LOGIC;
reg_9 : STD_LOGIC_VECTOR(CONST_1-1 downto 0);
reg_10 : STD_LOGIC_VECTOR(CONST_2-1 downto 0);
end record cm_t;
----------------------------------------
In the case of your first code, you are indeed adding a dependency to reset for reg_5 to reg_10. This is because of the if-else statement. This is the effective code you write for these registers.
if not(reset_reg) and load_reg then
cm_regB.reg_5 <= cm_regA.reg_5;
[...]
cm_regB.reg_10 <= cm_regA.reg_10;
end if;
So, you should separate the reset block from the other assignment. You can achieve that by using the fact that for signals only the last assignment in a process will be applied the next delta cycle. So something like this:
LOAD_DATA_PROCESS: process(clk_i)
begin
if rising_edge(clk_i) then
if load_reg then
cm_regB <= cm_regA;
end if;
if reset_reg then
cm_regB.reg_1 <= '0';
cm_regB.reg_2 <= '0';
cm_regB.reg_3 <= '0';
cm_regB.reg_4 <= '0';
end if;
end if;
end process;
My requirement is to compare the two array values using case statement. So I am using a for loop for all iterations.
Both are Input arrays : Memory_in array(expression) values are compared with sorted_array(choice) array values and Shaped_data is the output array (case statements).
I am getting static case error for my code below:
process (clk)
variable in_array: sorted;
variable out_array: sorted;
begin
-- in_array := sorted_array;
if rising_edge(clk) then
for i in 0 to 15 loop
case (Memory_in(i)) is
when sorted_array(0) => out_array(i) := x"F";
when sorted_array(1) => out_array(i) := x"E";
when sorted_array(2) => out_array(i) := x"D";
when sorted_array(3) => out_array(i) := x"C";
when sorted_array(4) => out_array(i) := x"B";
when sorted_array(5) => out_array(i) := x"A";
when sorted_array(6) => out_array(i) := x"9";
when sorted_array(7) => out_array(i) := x"8";
when sorted_array(8) => out_array(i) := x"7";
when sorted_array(9) => out_array(i) := x"6";
when sorted_array(10) => out_array(i) := x"5";
when sorted_array(11) => out_array(i) := x"4";
when sorted_array(12) => out_array(i) := x"3";
when sorted_array(13) => out_array(i) := x"2";
when sorted_array(14) => out_array(i) := x"1";
when sorted_array(15) => out_array(i) := x"0";
when others => null;--out_array(i) := "ZZZZ";
end case;
end loop;
Shaped_Data <= out_array;
end if;
end process;
The logic can be implemented using if else statement also but case statement would require less hardware. So I thought case statement would be better.
Is this error because of i value ? how do i do this ?
Whenever you find a big but regular structure, you can usually exploit that regularity. In this case, it simply means another loop.
What you have written reduces to something very like this:
process (clk)
variable out_array: sorted;
begin
-- in_array := sorted_array;
if rising_edge(clk) then
for i in 0 to 15 loop
for j in 0 to 15 loop
if Memory_in(i) = sorted_array(j) then
out_array(i) := 15 - j; -- maybe via type conversion
end if;
end loop;
end loop;
Shaped_Data <= out_array;
end if;
end process;
The syntax of a VHDL case statement is:
[Label:] case Expression is
when Choices => SequentialStatements... {any number of
when parts}
end case [Label];
Choices = Choice | Choice | ...
Choice = {one of}
ConstantExpression
Range
others {the last branch}
It's an error because the choice must be one of
constant expression
range
others
In your code the choice (sorted_array) is none of these; you say it is an "input".
Tip: Assign your case selection vector to a local process variable. (I don't know why, but, VHDL just requires you to do this.) Also, while you are assigning it to a local variable of the process, convert std_logic_vector to "unsigned" then "resize" it to the width of your case literals. Example:
process(amm_addr)
variable addr :unsigned(31 downto 0);
begin
addr := resize(unsigned(amm_addr),32);
...
case addr is
when X"00000008" => null;
when others => null;
end case;
end process;
A more detailed example:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all; --for "unsigned" type and "resize" funciton
entity testit is
generic(
aw :natural := 12;
dw :natural := 32
);
port(
clk :std_logic;
rstn :std_logic;
amm_addr :std_logic_vector(aw-1 downto 0);
amm_wen :std_logic;
amm_wdata :std_logic_vector(dw-1 downto 0);
amm_ren :std_logic;
amm_rdata :std_logic_vector(dw-1 downto 0);
amm_rvalid :std_logic
);
end entity;
architecture sim of testit is
signal reg1 :std_logic_vector(dw-1 downto 0);
signal reg2 :std_logic_vector(dw-1 downto 0);
signal reg3 :std_logic_vector(dw-1 downto 0);
signal reg4 :std_logic_vector(dw-1 downto 0);
begin
process(clk, rstn)
variable addr :unsigned(31 downto 0);
begin
addr := resize(unsigned(amm_addr),32);
if (rstn = '0') then
reg1 <= (others => '0');
reg2 <= (others => '0');
reg3 <= (others => '0');
reg4 <= (others => '0');
elsif (rising_edge(clk)) then
if (amm_wen = '1') then
case addr is
when X"00000000" => reg1 <= amm_wdata;
when X"00000001" => reg2 <= amm_wdata;
when X"00000002" => reg3 <= amm_wdata;
when X"00000003" => reg4 <= amm_wdata;
when others => null;
end case;
end if;
end if;
end process;
end architecture;
In one of my GUIs I load DICOM images. Sometimes they are just a volume and another dimension and when I load them in Matlab everything ends up where I want it.
handles.inf = dicominfo([filepath filename]);
handles.dat = dicomread(handles.inf);
size(handles.dat)
ans = 128 128 128 512
For an 128 by 128 by 128 volume at 512 timepoints for example (actually the third dimension would not even be 128, the third dimension is stacks, of which I don't know what it is). However sometimes There are more dimensions in the dicom, but the reader just puts all of them in the fourth dimension.
handles.inf = dicominfo([filepath filename]);
handles.dat = dicomread(handles.inf);
size(handles.dat)
ans = 128 128 1 4082
For a single 128 by 128 slice with 512 timepoints, two echoes and magnitude, phase, real and imaginary data for example.
It is then very hard to unscramble them. Manually I can do this for every DICOM I load but when in a GUI I would want to have a general approach that just creates a dimension in the array for each dimension in the dicom.
This is especially important not just for data-analysis, but also to transform the coordinates from image space to patient space. My own approach was to look at the header, but there's no guarantee that certain entries will work, and the order in which they are applied I can't find. The header entries I found so far:
inf.Rows;%inf.width;%inf.MRAcquisitionFrequencyEncodingSteps;%inf.MRAcquisitionPhaseEncodingStepsInPlane
inf.Columns;% inf.height; % inf.NumberOfKSpaceTrajectories;
inf.MRSeriesNrOfSlices
inf.MRSeriesNrOfEchoes
inf.MRSeriesNrOfDynamicScans
inf.MRSeriesNrOfPhases
inf.MRSeriesReconstructionNumber % not sure about this one
inf.MRSeriesNrOfDiffBValues
inf.MRSeriesNrOfDiffGradOrients
inf.MRSeriesNrOfLabelTypes
reshapeddat = reshape(dat, [all dimension sizes from header here]);
I'm not sure how to check if I've got all variables and what the right order for the reshape. Anybody knows of a sure-fire way to get all dimension sizes from the DICOM header and the order in which they are stacked?
Ok so I now manually go by all possible dimensions. When a stack also contains reconstructed data which has less dimensions than the rest, remove those first.
This is how I check the dimensions:
info = dicominfo(filename);
datorig = dicomread(filename);
%dimension sizes per frame
nrX = double(info.Rows); %similar nX;% info.width;% info.MRAcquisitionFrequencyEncodingSteps;% info.MRAcquisitionPhaseEncodingStepsInPlane
nrY = double(info.Columns); %similar nY;% info.height;% info.NumberOfKSpaceTrajectories;
%dimensions between frames
nrEcho = double(info.MRSeriesNrOfEchoes);
nrDyn = double(info.MRSeriesNrOfDynamicScans);
nrPhase = double(info.MRSeriesNrOfPhases);
nrSlice = double(info.MRSeriesNrOfSlices); %no per frame struct entry, calculate from offset.
%nr of frames
nrFrame = double(info.NumberOfFrames);
nrSeq = 1; % nSeq not sure how to interpret this, wheres the per frame struct entry?
nrBval = double(info.MRSeriesNrOfDiffBValues); % nB
nrGrad = double(info.MRSeriesNrOfDiffGradOrients); % info.MRSeriesNrOfPhaseContrastDirctns;%similar nGrad?
nrASL = 1; % info.MRSeriesNrOfLabelTypes;%per frame struct entry?
imtype = cell(1, nrFrame);
for ii = 1:nrFrame
%imtype(ii) = eval(sprintf('info.PerFrameFunctionalGroupsSequence.Item_%d.PrivatePerFrameSq.Item_1.MRImageTypeMR', ii));
imtype{ii} = num2str(eval(sprintf('info.PerFrameFunctionalGroupsSequence.Item_%d.PrivatePerFrameSq.Item_1.MRImageTypeMR', ii)));
end
imType = unique(imtype, 'stable');
nrType = length(imType);
This is how I reformat the dimensions:
%% count length of same dimension positions from start
if nrEcho > 1
for ii = 1:nrFrame
imecno(ii) = eval(sprintf('inf.PerFrameFunctionalGroupsSequence.Item_%d.PrivatePerFrameSq.Item_1.EchoNumber', ii));
end
lenEcho = find(imecno ~= imecno(1), 1, 'first') - 1;
else
lenEcho = nrFrame;
end
if nrDyn > 1
for ii = 1:nrFrame
imdynno(ii) = eval(sprintf('inf.PerFrameFunctionalGroupsSequence.Item_%d.PrivatePerFrameSq.Item_1.TemporalPositionIdentifier', ii));
end
lenDyn = find(imdynno ~= imdynno(1), 1, 'first') - 1;
else
lenDyn = nrFrame;
end
if nrPhase > 1
for ii = 1:nrFrame
imphno(ii) = eval(sprintf('inf.PerFrameFunctionalGroupsSequence.Item_%d.PrivatePerFrameSq.Item_1.MRImagePhaseNumber', ii));
end
lenPhase = find(imphno~=imphno(1), 1, 'first') - 1;
else
lenPhase = nrFrame;
end
if nrType > 1
q = 1;
imtyno(1, 1) = q;
for ii = 2:nrFrame
if imtype{:, ii-1} ~= imtype{:, (ii)}
q = q+1;
end
imtyno(1, ii) = q;
%for jj = 1:nrType
%if imtype{:,ii} == imType{:,jj}
% imtyno(1, ii) = jj;
%end
%end
end
if q ~= nrType
nrType = q;
end
lenType = find(imtyno ~= imtyno(1), 1, 'first') - 1;
else
lenType = nrFrame;
end
% slices are not numbered per frame, so get this indirectly from location
% currently not sure if working for all angulations
for ii = 1:nrFrame
imslice(:,ii) = -eval(['inf.PerFrameFunctionalGroupsSequence.Item_',sprintf('%d', ii),'.PlanePositionSequence.Item_1.ImagePositionPatient']);
end
% stdsl = std(imslice,[],2); --> Assumption
% dirsl = max(find(stdsl == max(stdsl)));
imslices = unique(imslice', 'rows')';
if nrSlice > 1
for ii = 1:nrFrame
for jj = 1:nrSlice
if imslice(:,ii) == imslices(:,nrSlice - (jj-1)); %dirsl or :?
imslno(1, ii) = jj;
end
end
end
lenSlice = find(imslno~=imslno(1), 1, 'first')-1;
else
lenSlice = nrFrame;
end
if nrBval > 1
for ii = 1:nrFrame
imbno(ii) = eval(sprintf('inf.PerFrameFunctionalGroupsSequence.Item_%d.PrivatePerFrameSq.Item_1.MRImageDiffBValueNumber', ii));
end
lenBval = find(imbno~=imbno(1), 1, 'first') - 1;
else
lenBval = nrFrame;
end
if nrGrad > 1
for ii = 1:nrFrame
imgradno(ii) = eval(sprintf('inf.PerFrameFunctionalGroupsSequence.Item_%d.PrivatePerFrameSq.Item_1.MRImageGradientOrientationNumber', ii));
end
lenGrad = find(imgradno~=imgradno(1), 1, 'first')-1;
else
lenGrad = inf.NumberOfFrames;
end
lenSeq = nrFrame; % dont know how to get this information per frame, in my case always one
lenASL = nrFrame; % dont know how to get this information per frame, in my case always one
%this would have been the goal format
goaldim = [nrSlice nrEcho nrDyn nrPhase nrType nrSeq nrBval nrGrad nrASL]; % what we want
goallen = [lenSlice lenEcho lenDyn lenPhase lenType lenSeq lenBval lenGrad lenASL]; % what they are
[~, permIX] = sort(goallen);
dicomdim = zeros(1, 9);
for ii = 1:9
dicomdim(1, ii) = goaldim(permIX(ii));
end
dicomdim = [nrX nrY dicomdim];
%for any possible zero dimensions from header use a 1 instead
dicomdim(find(dicomdim == 0)) = 1;
newdat = reshape(dat, dicomdim);
newdim = size(newdat);
newnonzero = length(newdim(3:end));
goalnonzero = permIX(1:newnonzero);
[dummyy, goalIX] = sort(goalnonzero);
goalIX = [1 2 goalIX+2];
newdat = permute(newdat, goalIX);
newdat = reshape(newdat, [nrX nrY goaldim]);
When Ive used this as a function for a longer period and debugged it a bit I might post in on the file exchange of mathworks.
I have this warnig in my code for a FSM:
WARNING:Xst:2170 - Unit P22_MustangSecuentialTailLight_Structural : the following signal(s) form a combinatorial loop: Lights<5>, U1/next_state_cmp_eq0000, next_state_int<0>, pres_state_int<0>.
WARNING:Xst:2170 - Unit P22_MustangSecuentialTailLight_Structural : the following signal(s) form a combinatorial loop: Lights<4>, next_state_int<1>, pres_state_int<1>.
WARNING:Xst:2170 - Unit P22_MustangSecuentialTailLight_Structural : the following signal(s) form a combinatorial loop: next_state_int<2>, U1/next_state_cmp_eq0003, Lights<3>, pres_state_int<2>.
WARNING:Xst:2170 - Unit P22_MustangSecuentialTailLight_Structural : the following signal(s) form a combinatorial loop: next_state_int<3>, pres_state_int<4>, U1/next_state_cmp_eq0013, pres_state_int<3>, Lights<2>, next_state_int<4>.
Its for a loop made in the code, the image of my diagram
But that enbedded signal(pres_state_int) is necessary for update the next state logic block. The code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.States.all;
entity P22_MustangSecuentialTailLight_Structural is
Port ( Lturn : in STD_LOGIC;
Rturn : in STD_LOGIC;
Hazard : in STD_LOGIC;
Rst : in STD_LOGIC;
Break : in STD_LOGIC;
Clk100MHz : in STD_LOGIC;
Lights : out STD_LOGIC_VECTOR (5 downto 0));
end P22_MustangSecuentialTailLight_Structural;
architecture Behavioral of P22_MustangSecuentialTailLight_Structural is
component NextStateLogic
port (
BLRH : in STD_LOGIC_VECTOR (3 downto 0);
pres_state : in STD_LOGIC_VECTOR (4 downto 0);
next_state : out STD_LOGIC_VECTOR (4 downto 0));
end component;
component CurrentStateRegister
port (
pres_state_b : out STD_LOGIC_VECTOR (4 downto 0);
next_state_b : in STD_LOGIC_VECTOR (4 downto 0);
Rst : in STD_LOGIC;
Clk : in STD_LOGIC );
end component;
component OutputLogic
port (
pres_state_c : in STD_LOGIC_VECTOR (4 downto 0);
Lights : out STD_LOGIC_VECTOR (5 downto 0));
end component;
component Clk1Hz
port (
Rst : in STD_LOGIC;
Clk_in : in STD_LOGIC;
Clk_out : out STD_LOGIC);
end component;
--Embedded signal declaration
signal LRH_int : STD_LOGIC_VECTOR (3 downto 0);
signal next_state_int : state_values := ST0;
signal pres_state_int : state_values := ST0;
signal Clk1Hz_int : STD_LOGIC;
begin
LRH_int <= Break & Lturn & Rturn & Hazard;
U1 : NextStateLogic
port map(
BLRH => LRH_int,
pres_state => pres_state_int,
next_state => next_state_int
);
U2 : CurrentStateRegister
port map(
pres_state_b => pres_state_int,
next_state_b => next_state_int,
Rst => Rst,
Clk => Clk1Hz_int
);
U3 : OutputLogic
port map(
pres_state_c => pres_state_int,
Lights => Lights
);
U4 : Clk1Hz
port map(
Rst => Rst,
Clk_in => Clk100MHz,
Clk_out => Clk1Hz_int
);
end Behavioral;
Next is the package use for encoding the code:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
package States is
subtype state_values is std_logic_vector(4 downto 0);
constant ST0: state_values := "00000";
constant ST1: state_values := "00001";
constant ST2: state_values := "00010";
constant ST3: state_values := "00011";
constant ST4: state_values := "00100";
constant ST5: state_values := "00101";
constant ST6: state_values := "00110";
constant ST7: state_values := "00111";
constant ST8: state_values := "01000";
constant ST9: state_values := "01001";
constant ST10: state_values := "01010";
constant ST11: state_values := "01011";
constant ST12: state_values := "01100";
constant ST13: state_values := "01101";
constant ST14: state_values := "01110";
constant ST15: state_values := "01111";
constant ST16: state_values := "10000";
signal pres_state, next_state: state_values;
end States;
NextStateLogic component code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.States.all;
entity NextStateLogic is
Port( BLRH : in STD_LOGIC_VECTOR (3 downto 0);
pres_state : in STD_LOGIC_VECTOR (4 downto 0);
next_state : out STD_LOGIC_VECTOR (4 downto 0));
end NextStateLogic;
architecture NextStateLogicl of NextStateLogic is
begin
FSM: process (pres_state, BLRH)
begin
case pres_state is
when "00000" =>
case BLRH is
when "0000" => next_state <= "00000";--ST0; -- All off
when "0010" => next_state <= "00100";--ST4; -- Right Turn
when "0100" => next_state <= "00111";--ST7; -- Left Turn
when "0110" => next_state <= "00101";--ST5; -- All off
when others => next_state <= "00001";--ST1; -- Hazard
end case;
when "00001" => next_state <= "00010";--ST2;
when "00010" => next_state <= "00011";
when "00011" =>
case BLRH is
when "1000" => next_state <= "00011"; -- Break
when "1110" => next_state <= "00011"; --
when "1010" => next_state <= "01101"; -- Right Turn & Break
when "1100" => next_state <= "01010"; -- Left Turn & Break
when others => next_state <= "00000"; -- Hazard
end case;
when "00100" => next_state <= "00101";
when "00101" => next_state <= "00110";
when "00110" => next_state <= "00000";
when "00111" => next_state <= "01000";
when "01000" => next_state <= "01001";
when "01001" => next_state <= "01010";
when "01010" => next_state <= "01011";
when "01011" => next_state <= "01100";
when "01100" =>
case BLRH is
when "1100" => next_state <= "01111"; -- Right Turn & Break
when "1010" => next_state <= "10000"; -- Left Turn & Break
when others => next_state <= "00000";
end case;
when "01101" => next_state <= "01110";
when "01110" => next_state <= "01100";
when "01111" => next_state <= "01010";
when "10000" => next_state <= "01101";
-- Include when others to avoid latches
when others => next_state <= "00000";
end case;
end process FSM;
end NextStateLogicl;
CurrentStateRegister component code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity CurrentStateRegister is
Port(
pres_state_b : out STD_LOGIC_VECTOR (4 downto 0);
next_state_b : in STD_LOGIC_VECTOR (4 downto 0);
Rst : in STD_LOGIC;
Clk : in STD_LOGIC
);
end CurrentStateRegister;
architecture CurrentStateRegister of CurrentStateRegister is
begin
StateReg: process (Clk,Rst,next_state_b)
begin
if (Rst = '1') then
pres_state_b <= "00000";
elsif Clk = '1' then
pres_state_b <= next_state_b;
else
pres_state_b<= "00000";
end if;
end process StateReg;
end CurrentStateRegister;
OutputLogic component code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity OutputLogic is
Port(
pres_state_c : in STD_LOGIC_VECTOR (4 downto 0);
Lights : out STD_LOGIC_VECTOR (5 downto 0));
end OutputLogic;
architecture OutputLogic of OutputLogic is
begin
Outputs: process (pres_state_c)
begin
case pres_state_c is
when "00000" => Lights <= "000000";
----------------------------------------------- Hazard
when "00001" => Lights <= "001100";
when "00010" => Lights <= "011110";
when "00011" => Lights <= "111111";
----------------------------------------------- Right Turn
when "00100" => Lights <= "000100";
when "00101" => Lights <= "000110";
when "00110" => Lights <= "000111";
----------------------------------------------- Left Turn
when "00111" => Lights <= "001000";
when "01000" => Lights <= "011000";
when "01001" => Lights <= "111000";
----------------------------------------------- Right Turn & Break
when "01010" => Lights <= "001111";
when "01011" => Lights <= "011111";
-----------------------------------------------
when "01111" => Lights <= "000111";
when "01100" => Lights <= "111111"; -- Common Case
when "10000" => Lights <= "111000";
----------------------------------------------- Left Turn & Break
when "01101" => Lights <= "111100";
when "01110" => Lights <= "111110";
when others => Lights <= "000000";
end case;
end process Outputs;
end OutputLogic;
And finally the Clk1Hz component code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Clk1Hz is
port (
Rst : in STD_LOGIC;
Clk_in : in STD_LOGIC;
Clk_out : out STD_LOGIC);
end Clk1Hz;
architecture Clk1Hz of Clk1Hz is
-- Definition of embedded signals and constants
-- Constants used for frequency division
constant Fosc : integer := 100000000; --Frecuencia del oscilador de tabletas NEXYS 3
constant Fdiv : integer := 5; --Frecuencia deseada del divisor
constant CtaMax : integer := Fosc / Fdiv; --Cuenta maxima a la que hay que llegar
-- Signal used by the frequency division process
signal Cont : integer range 0 to CtaMax;
begin
-- Frequency divider to obtain a 2Hz signal from
-- the 100 MHz board oscillator
FreqDiv: process (Rst, Clk_in)
begin
if Rst = '1' then
Cont <= 0;
elsif (rising_edge(Clk_in)) then
if Cont = CtaMax - 1 then
Cont <= 0;
Clk_out <= '1';
else
Cont <= Cont + 1;
Clk_out <= '0';
end if;
end if;
end process FreqDiv;
end Clk1Hz;
Iam missing something?? Is there another way to instanciate the component NextStateLogic?
Thanks:D
In CurrentStateRegister, you need to test for rising_edge(clk) instead of clk = '1'. Your current code infers a latch instead of a register, causing a loop whenever clk = '1'. Also, lose the final else in the ControlStateRegister module:
StateReg: process (Clk,Rst,next_state_b)
begin
if (Rst = '1') then
pres_state_b <= "00000";
elsif (rising_edge(Clk)) then
pres_state_b <= next_state_b;
end if;
end process StateReg;
Question: Make Calendar Which Shows Month Number and Days of Month ?
Write Both in Combinational and Sequential VHDL Constructs ?
I am new on this VHDL and i have a quiz on Monday .. Anyone have any idea about where to start and how to start writing the programming in VHDL ?
Any help will be greatly appreciated ..
Thanks
Here is something to get you started with your assignment. It accepts the binary value of month, 1-12, and if it is a leap year or not, and outputs the number of days in that month. This is done without a clock (combinatorial/asynchronous logic).
I think you can take this and determine the best way to use sequential statements to create an alternative implementation based on what you assignment is asking for.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Days_In_Month is
port (
I_MONTH : in unsigned(3 downto 0);
I_LEAP_YEAR : in std_logic;
O_DAYS_IN_MONTH : out unsigned(4 downto 0)
);
end entity Days_In_Month;
architecture Days_In_Month_combinatorial of Days_In_Month is
signal month_30d : std_logic;
signal month_28d : std_logic;
signal month_31d : std_logic;
signal month_29d : std_logic;
begin
month_30d <= '1' when I_MONTH = 9 or
I_MONTH = 4 or
I_MONTH = 6 or
I_MONTH = 11
else '0';
month_28d <= '1' when I_MONTH = 2 and
I_LEAP_YEAR = '0'
else '0';
month_29d <= '1' when I_MONTH = 2 and
I_LEAP_YEAR = '1'
else '0';
month_31d <= '1' when month_30d = '0' and
month_28d = '0' and
month_29d = '0'
else '0';
O_DAYS_IN_MONTH <= to_unsigned(30,O_DAYS_IN_MONTH'length) when month_30d = '1' else
to_unsigned(28,O_DAYS_IN_MONTH'length) when month_28d = '1' else
to_unsigned(29,O_DAYS_IN_MONTH'length) when month_29d = '1' else
to_unsigned(31,O_DAYS_IN_MONTH'length) when month_31d = '1'
else to_unsigned(0,O_DAYS_IN_MONTH'length);
end architecture Days_In_Month_combinatorial;