vhdl code not working

Guest
I have created a register file that holds 4 32 bit registers.Now i would like to check whether the first 3 bits of the first register(CTL) is 1 and then check if the 1st bit of 2nd register is 1 .If so the BC_en bit should go high.....which is not happening....can anyone please see the code below and help me?

..............................................................................
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std_UNSIGNED.ALL;

entity cntrregFile is
port
(
input : in std_logic_vector (31 downto 0);
writeEnable : in std_logic;
clk : in std_logic;
readregSel : in std_logic_vector (2 downto 0);
writeregSel : in std_logic_vector (2 downto 0);
readEnable : in std_logic;
output : out std_logic_vector (31 downto 0);
bc_en : out std_logic
);
end cntrregFile;
architecture behavioral of cntrregFile is
type registerFile is array(0 to 3) of std_logic_vector(31 downto 0);
signal registers : registerFile;
signal CTL : std_logic_vector(31 downto 0);
signal BC_CTL : std_logic_vector(31 downto 0);
signal BC_FIFO_CTL : std_logic_vector(31 downto 0);
signal ENCDEC_CTL : std_logic_vector(31 downto 0);

begin

process (clk,writeregSel,writeEnable,readregSel,readEnable) is

begin

if (rising_edge(clk) and writeEnable='1' ) then

if ( writeregSel="000") then
registers (to_integer(writeregSel)) <= input ;
elsif ( writeregSel="001") then
registers (to_integer(writeregSel)) <= input ;
elsif ( writeregSel="010") then
registers (to_integer(writeregSel)) <= input ;
elsif ( writeregSel="011") then
registers (to_integer(writeregSel)) <= input ;

end if;
elsif (rising_edge(clk) and readEnable='1') then
if (readregSel="000") then
CTL <= registers(to_integer(readregSel));
output <= CTL;

elsif(readregSel="001") then
BC_CTL <= registers(to_integer(readregSel));
output<= BC_CTL;
elsif(readregSel="010") then
BC_FIFO_CTL <= registers(to_integer(readregSel));
output<= BC_FIFO_CTL;
elsif(readregSel="011") then
ENCDEC_CTL <= registers(to_integer(readregSel));
output<=ENCDEC_CTL ;

end if;
end if;
end process;

process (clk,CTL,BC_CTL) is

begin

if (CTL(0)= '1') and (CTL(1)='1') and
(CTL(2)='0') and (CTL(3)='0')then
if (BC_CTL(0) ='1') then
bc_en<= '1';
else
bc_en<='0';
end if;
end if;

end process;
end behavioral;
 
On Thursday, February 6, 2020 at 6:29:01 AM UTC-5, sweety...@gmail.com wrote:
I have created a register file that holds 4 32 bit registers.Now i would like to check whether the first 3 bits of the first register(CTL) is 1 and then check if the 1st bit of 2nd register is 1 .If so the BC_en bit should go high.....which is not happening....can anyone please see the code below and help me?

.............................................................................
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std_UNSIGNED.ALL;

entity cntrregFile is
port
(
input : in std_logic_vector (31 downto 0);
writeEnable : in std_logic;
clk : in std_logic;
readregSel : in std_logic_vector (2 downto 0);
writeregSel : in std_logic_vector (2 downto 0);
readEnable : in std_logic;
output : out std_logic_vector (31 downto 0);
bc_en : out std_logic
);
end cntrregFile;
architecture behavioral of cntrregFile is
type registerFile is array(0 to 3) of std_logic_vector(31 downto 0);
signal registers : registerFile;
signal CTL : std_logic_vector(31 downto 0);
signal BC_CTL : std_logic_vector(31 downto 0);
signal BC_FIFO_CTL : std_logic_vector(31 downto 0);
signal ENCDEC_CTL : std_logic_vector(31 downto 0);

begin

process (clk,writeregSel,writeEnable,readregSel,readEnable) is

begin

if (rising_edge(clk) and writeEnable='1' ) then

if ( writeregSel="000") then
registers (to_integer(writeregSel)) <= input ;
elsif ( writeregSel="001") then
registers (to_integer(writeregSel)) <= input ;
elsif ( writeregSel="010") then
registers (to_integer(writeregSel)) <= input ;
elsif ( writeregSel="011") then
registers (to_integer(writeregSel)) <= input ;

end if;
elsif (rising_edge(clk) and readEnable='1') then
if (readregSel="000") then
CTL <= registers(to_integer(readregSel));
output <= CTL;

elsif(readregSel="001") then
BC_CTL <= registers(to_integer(readregSel));
output<= BC_CTL;
elsif(readregSel="010") then
BC_FIFO_CTL <= registers(to_integer(readregSel));
output<= BC_FIFO_CTL;
elsif(readregSel="011") then
ENCDEC_CTL <= registers(to_integer(readregSel));
output<=ENCDEC_CTL ;

end if;
end if;
end process;

process (clk,CTL,BC_CTL) is

begin

if (CTL(0)= '1') and (CTL(1)='1') and
(CTL(2)='0') and (CTL(3)='0')then
if (BC_CTL(0) ='1') then
bc_en<= '1';
else
bc_en<='0';
end if;
end if;

end process;
end behavioral;

A couple of small issues that aren't your problem. A clocked process only needs the signals in the sensitivity list that are prerequisites to any of the outputs changing. So it should include the clock signal and if you had an async input such as reset, that too. But only if the reset or any other signal is asynchronous. So clean up your sensitivity list and your simulations will run faster.

Then by convention there is an outer conditional to detect the rising edge of the clock and all other logic is inside this structure as separate conditionals. I can't say this causes any problems, but I've never seen anyone do it in two separate conditionals so I can't say for sure. But it will be easier to get help if your code has the same basic structure as everyone else's.

Your use of IEEE.STD_LOGIC_UNSIGNED along with ieee.numeric_std_UNSIGNED has several problems. The former is deprecated and you should stop using it. The latter is not even a thing... the name is ieee.numeric_std. It includes both signed and unsigned types.


Another style issue which may be causing a failure (not sure) is with writing the registers. You are using a conditional to decode the register select, then you are addressing the register directly by turning writeregSel into an integer. You only need to do one of those things, not both.

There is a mismatch with the number of registers (4) and the possible registers selected by the select lines (8 or 3 depending on whether or not they are 1-hot). So which is right?

Do you realize that when reading you have a register delay between the read enable and the register value being saved in CTL, BC_CTL, BC_FIFO_CTL and ENCDEC_CTL? Then you add another register delay before assigning those values to output? I'm not saying this is wrong, I just want to make sure you have it right from the assignment.

The register delays can be important to your application and in particular to the decoding. Right now the decode is on the registers CTL and BC_CTL while you are also storing the data in the register file "registers". registers is updated when you write the register file. CTL and BC_CTL are only written when you read the register file.

So I think you have many errors in your code that are logical errors. I suggest that you try drawing a block diagram of the logic you would use to implement this design. Show the registers, data flow and decodes. Then you can write code to describe that structure and it should be a closer match.

--

Rick C.

- Get 1,000 miles of free Supercharging
- Tesla referral code - https://ts.la/richard11209
 
On 2020-02-06 11:04, Rick C wrote:
On Thursday, February 6, 2020 at 6:29:01 AM UTC-5, sweety...@gmail.com wrote:
I have created a register file that holds 4 32 bit registers.Now i would like to check whether the first 3 bits of the first register(CTL) is 1 and then check if the 1st bit of 2nd register is 1 .If so the BC_en bit should go high.....which is not happening....can anyone please see the code below and help me?

............................................................................
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.numeric_std_UNSIGNED.ALL;

entity cntrregFile is
port
(
input : in std_logic_vector (31 downto 0);
writeEnable : in std_logic;
clk : in std_logic;
readregSel : in std_logic_vector (2 downto 0);
writeregSel : in std_logic_vector (2 downto 0);
readEnable : in std_logic;
output : out std_logic_vector (31 downto 0);
bc_en : out std_logic
);
end cntrregFile;
architecture behavioral of cntrregFile is
type registerFile is array(0 to 3) of std_logic_vector(31 downto 0);
signal registers : registerFile;
signal CTL : std_logic_vector(31 downto 0);
signal BC_CTL : std_logic_vector(31 downto 0);
signal BC_FIFO_CTL : std_logic_vector(31 downto 0);
signal ENCDEC_CTL : std_logic_vector(31 downto 0);

begin

process (clk,writeregSel,writeEnable,readregSel,readEnable) is

begin

if (rising_edge(clk) and writeEnable='1' ) then

if ( writeregSel="000") then
registers (to_integer(writeregSel)) <= input ;
elsif ( writeregSel="001") then
registers (to_integer(writeregSel)) <= input ;
elsif ( writeregSel="010") then
registers (to_integer(writeregSel)) <= input ;
elsif ( writeregSel="011") then
registers (to_integer(writeregSel)) <= input ;

end if;
elsif (rising_edge(clk) and readEnable='1') then
if (readregSel="000") then
CTL <= registers(to_integer(readregSel));
output <= CTL;

elsif(readregSel="001") then
BC_CTL <= registers(to_integer(readregSel));
output<= BC_CTL;
elsif(readregSel="010") then
BC_FIFO_CTL <= registers(to_integer(readregSel));
output<= BC_FIFO_CTL;
elsif(readregSel="011") then
ENCDEC_CTL <= registers(to_integer(readregSel));
output<=ENCDEC_CTL ;

end if;
end if;
end process;

process (clk,CTL,BC_CTL) is

begin

if (CTL(0)= '1') and (CTL(1)='1') and
(CTL(2)='0') and (CTL(3)='0')then
if (BC_CTL(0) ='1') then
bc_en<= '1';
else
bc_en<='0';
end if;
end if;

end process;
end behavioral;

A couple of small issues that aren't your problem. A clocked process only needs the signals in the sensitivity list that are prerequisites to any of the outputs changing. So it should include the clock signal and if you had an async input such as reset, that too. But only if the reset or any other signal is asynchronous. So clean up your sensitivity list and your simulations will run faster.

Then by convention there is an outer conditional to detect the rising edge of the clock and all other logic is inside this structure as separate conditionals. I can't say this causes any problems, but I've never seen anyone do it in two separate conditionals so I can't say for sure. But it will be easier to get help if your code has the same basic structure as everyone else's.

Your use of IEEE.STD_LOGIC_UNSIGNED along with ieee.numeric_std_UNSIGNED has several problems. The former is deprecated and you should stop using it. The latter is not even a thing... the name is ieee.numeric_std. It includes both signed and unsigned types.


Another style issue which may be causing a failure (not sure) is with writing the registers. You are using a conditional to decode the register select, then you are addressing the register directly by turning writeregSel into an integer. You only need to do one of those things, not both.

There is a mismatch with the number of registers (4) and the possible registers selected by the select lines (8 or 3 depending on whether or not they are 1-hot). So which is right?

Do you realize that when reading you have a register delay between the read enable and the register value being saved in CTL, BC_CTL, BC_FIFO_CTL and ENCDEC_CTL? Then you add another register delay before assigning those values to output? I'm not saying this is wrong, I just want to make sure you have it right from the assignment.

The register delays can be important to your application and in particular to the decoding. Right now the decode is on the registers CTL and BC_CTL while you are also storing the data in the register file "registers". registers is updated when you write the register file. CTL and BC_CTL are only written when you read the register file.

So I think you have many errors in your code that are logical errors. I suggest that you try drawing a block diagram of the logic you would use to implement this design. Show the registers, data flow and decodes. Then you can write code to describe that structure and it should be a closer match.
I'll echo Rick's comments. A clocked process should contain only the
clock signal in the sensitivity list, and possibly also the reset signal
if you are using an asynchronous reset. Your second process shouldn't
contain the clk signal because it is not a clocked process.

Forget the STD_LOGIC_ARITH and STD_LOGIC_UNSIGNED packages. Those are
old, non-standard packages that were developed by Synopsis before IEEE
came out with the numberic_std package. VHDL purists will argue that
they shouldn't even be in the ieee library, because they were not
developed by IEEE, but that is where tool vendors usually put them. Use
ieee.numeric_std instead.

You need to understand the difference between variable assignments and
signal assignments in VHDL. Variable assignments happen immediately,
like in common programming languages, before the next statement is
executed. Signal assignments do not happen immediately. What they do is
put an event into the simulator's event queue to be processed later.

For example, let's take a look at two statements from your code:
CTL <= registers(to_integer(readregSel));
output <= CTL;
What that says is:
Put an event into the simulator's event queue to assign the current
value of registers(0) to the signal CTL.
Put an event into the simulator's event queue to assign the current
value of CTL to the signal "output".
So CTL and OUTPUT do not necessary get the same value. OUTPUT gets the
value that CTL already had BEFORE the assignment
CTL <= registers(to_integer(readregSel));
got carried out.

Variable assignments in VHDL take place immediately. Variables don't
trigger events or other processes. Signals in VHDL hold both a value and
time and event information. Signals can trigger other processes.

It isn't clear from your code just what you were trying to accomplish,
but take a look at the way I recoded it to see if it might be closer to
your intentions:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.ALL;

entity cntrregFile is
port
(
input : in std_logic_vector (31 downto 0);
writeEnable : in std_logic;
clk : in std_logic;
readregSel : in std_logic_vector (2 downto 0);
writeregSel : in std_logic_vector (2 downto 0);
readEnable : in std_logic;
output : out std_logic_vector (31 downto 0);
bc_en : out std_logic
);
end cntrregFile;

architecture behavioral of cntrregFile is
type registerFile is array(0 to 3) of std_logic_vector(31 downto 0);
signal registers : registerFile;
signal CTL : std_logic_vector(31 downto 0);
signal BC_CTL : std_logic_vector(31 downto 0);
signal BC_FIFO_CTL : std_logic_vector(31 downto 0);
signal ENCDEC_CTL : std_logic_vector(31 downto 0);

begin

clk_proc: process (clk) is
variable reg_addr : integer range 0 to 3;
begin
if (rising_edge(clk) ) then
if writeEnable='1' and writeregSel(2)='0' then
reg_addr := to_integer(writeregSel(1 downto 0));
registers(reg_addr) <= input ;
end if;
if readEnable='1' then
if (readregSel="000") then
CTL <= registers(0);
end if;
if (readregSel="001") then
BC_CTL <= registers(1);
end if;
if (readregSel="010") then
BC_FIFO_CTL <= registers(2);
end if;
if (readregSel="011") then
ENCDEC_CTL <= registers(3);
end if;
if readregSel(2)='0' then
reg_addr := to_integer(readregSel(1 downto 0));
output <= registers(reg_addr);
end if;
end if;
end if;
end process;

bc_en <= CTL(0) and CTL(1) and not CTL(2) and BC_CTL(0);

end behavioral;


Charles Bailey
 
Good comments all. I just want to post my library inclusion code as another example. I typically use the IEEE standard libraries as well as some of my own project oriented definitions.

library ieee;
use ieee.std_logic_1164.all;
Use ieee.numeric_std.all;

Library Common;
Use Common.Stuff.all;
Use Common.conversions.all;

Library Hardware;
Use Hardware.IRIG_Defs.all;

The Common library has my own code I use on every project, hence the name "Common". The last library is a project specific library mostly with constants for hardware registers, but also with functions that handle simple data conversions, bit extractions and etc.

It's very useful to have your own libraries that you can easily port between projects. The only problem with this is that every tool seems to expect you to put your code in a directory structure they create for your project rather than putting all their stuff in a sub-directory under yours to keep it out of sight, out of mind. So these library files often get copied around rather than trying to point back to another file outside of the project directory.

I believe I've tried to talk to the vendors about that, but they are so entrenched in their ways changing anything so simple as the location of the source code in the directory structure is a virtual movement of the mountain. So rather than being able to simply delete their directory structure when I want to back up and archive my code, I have to manually dig in and delete intertwined files.

--

Rick C.

+ Get 1,000 miles of free Supercharging
+ Tesla referral code - https://ts.la/richard11209
 
On Wednesday, February 12, 2020 at 10:13:33 AM UTC-5, Rick C wrote:
It's very useful to have your own libraries that you can easily port between projects. The only problem with this is that every tool seems to expect you to put your code in a directory structure they create for your project rather than putting all their stuff in a sub-directory under yours to keep it out of sight, out of mind. So these library files often get copied around rather than trying to point back to another file outside of the project directory.

If you use version control such as Subversion and of course many others, then the true master copy of the file is inside that version control system, not in some other folder on your hard drive. Each individual project would reference the source from version control and place it where the tool is happy about it. No need to reference source files that are in some other folder.

Kevin Jennings
 
On 2/12/20 6:45 PM, KJ wrote:
On Wednesday, February 12, 2020 at 10:13:33 AM UTC-5, Rick C wrote:

It's very useful to have your own libraries that you can easily port between projects. The only problem with this is that every tool seems to expect you to put your code in a directory structure they create for your project rather than putting all their stuff in a sub-directory under yours to keep it out of sight, out of mind. So these library files often get copied around rather than trying to point back to another file outside of the project directory.

If you use version control such as Subversion and of course many others, then the true master copy of the file is inside that version control system, not in some other folder on your hard drive. Each individual project would reference the source from version control and place it where the tool is happy about it. No need to reference source files that are in some other folder.

Kevin Jennings

Expanding on that, we use Subversion to control all of our projects, and all of
our common libraries as well. Projects using those libraries get local
checkouts of the library using svn:externals (git has a similar thing called
submodules). Then when we make release tags from the project, we insist that it
be against a release tagged version of the library too.
 
Thankyou so much everyone for replying. I've made some changes to my code as you all have suggested and now its working perfectly.
 
On Tuesday, February 18, 2020 at 3:41:21 AM UTC-5, sweety...@gmail.com wrote:
> Thankyou so much everyone for replying. I've made some changes to my code as you all have suggested and now its working perfectly.

If you want some constructive criticism you can post your final code here. I can assure you that working code is not your best goal. There are folks here with lots of experience who can help you write code that is easier to read and easier to debug.

--

Rick C.

-- Get 1,000 miles of free Supercharging
-- Tesla referral code - https://ts.la/richard11209
 

Welcome to EDABoard.com

Sponsor

Back
Top