Forum Discussion
Reading data from a ROM
I have created a ROM-1port via the MegaWizard which also has a .mif file and in my top level entity I have to instantiate that rom, but I don't know how to access the data from it.
My .mif file is this:
WIDTH=8;
DEPTH=2;
ADDRESS_RADIX=UNS;
DATA_RADIX=UNS;
CONTENT BEGIN
0 : 14;
1 : 21;
END;
And the rom component is:
component rom_int
port
(
address : in std_logic_vector(4 downto 0);
clock : in std_logic := '1';
q : out std_logic_vector(15 downto 0)
);
end component;
I actually wanted an address with only 2 positions but you can't on the megawizard and quartus fills the rest with zeros. Anyway, so I have to send 2 adresses to the rom so it returns me the output data, and each adress is 8 bits and the output is 16 bits (0000 1110 0001 0101 (14 21)). How do I write the code for the 2 adresses for the instantiation?11 Replies
- Altera_Forum
Honored Contributor
- Altera_Forum
Honored Contributor
That's the thing though, I need to use an external file like a .txt or .mif to initialize the memory and the intention is that the text file contains the version of the firmware and that file is controlled by another software, it's not going to be a fixed value, so I need a code that won't change, what will be changing always is the txt/mif file.
So I need a way to access those 2 adresses, I'm not sure if it's best to do it with a RAM or ROM, I tried both ways. - Altera_Forum
Honored Contributor
It appears to me that you simply need to add some addressing logic to your RAM. This could easily be done with a state machine, where you use a variable counter that gets incremented every other state, and the interposing states is where you read the output of your RAM. This works well with single clock synchronous RAM's. I've done this before and had good success. You just need a trigger event to tell the state machine to start; this could be in your FPGA fabric somewhere or even an external switch to tell the memory controller to execute. -James
- Altera_Forum
Honored Contributor
It's what I did, but I don't seem to get anything on the output... tried several different ways too.
Here's the state machine:
How can I be sure the .mif file was loaded? I don't know what is going wrong... James could you please post a code of what you meant?port ( -- 50MHz clock clock : in std_logic; reset : in std_logic; ver : out std_logic_vector(15 downto 0) ); ---------- component rom -- MegaWizard created rom port ( address : in std_logic_vector(4 downto 0); clock : in std_logic; q : out std_logic_vector(7 downto 0) ); signal addr_rom : std_logic_vector(4 downto 0); signal data_out_rom : std_logic_vector(7 downto 0); type state is (addr0, addr1); signal st : state; ---------- rom_inst : rom port map ( address => addr_rom, clock => clock, q => data_out_rom ); process(reset, clock) begin if reset = '1' then st <= addr0; elsif rising_edge(clock) then case st is when addr0 => addr_rom <= "00000"; ver(15 downto 8) <= data_out_rom; st <= addr1; when addr1 => addr_rom <= "00001"; ver(7 downto 0) <= data_out_rom; st <= addr0; when others => st <= addr0; end case; end if; end process; - Altera_Forum
Honored Contributor
Hello Carili.
In the state machine when you place the address of ROM in the first state: when addr0 => addr_rom <= "00000"; ver(15 downto 8) <= data_out_rom; st <= addr1; you can't get the data in the same state you place the address. You must read it in the addr1. - Altera_Forum
Honored Contributor
What you are attempting I have done in the past to store hardware versions and software build numbers but I had Nios II reading out the values.
Perhaps you can skip using the ROM and just 'include a value defined in a verilog include file that is generated by your build system. In the include file you could just have something like 'define VERSION_NUMBER <machine generated version number> and in your hardware design refer to that value. - Altera_Forum
Honored Contributor
BadOmen:
Well I never did anything in verilog, so I wouldn't quite know how that works also I'm not too familiar with Nios II, and if you say using the ROM is really not going to work then I guess what I'm doing is pointless =\... I was really hoping that I was missing something on that ROM. bertulus: I did what you said and the state machine works now, but I'm still not getting anything on my screen (that output of the fpga goes to a microcontroller and then to a screen). So I'm really wondering if this actually works or not at all to the purpose I need. - Altera_Forum
Honored Contributor
Can you explain the whole project your trying to do? It would be easier to find the problem.
- Altera_Forum
Honored Contributor
Your code below is a good attempt, however, you need something where you increment the address, then read:
--- Quote Start --- It's what I did, but I don't seem to get anything on the output... tried several different ways too. Here's the state machine:
How can I be sure the .mif file was loaded? I don't know what is going wrong... James could you please post a code of what you meant? --- Quote End --- So something like this:port ( -- 50MHz clock clock : in std_logic; reset : in std_logic; ver : out std_logic_vector(15 downto 0) ); ---------- component rom -- MegaWizard created rom port ( address : in std_logic_vector(4 downto 0); clock : in std_logic; q : out std_logic_vector(7 downto 0) ); signal addr_rom : std_logic_vector(4 downto 0); signal data_out_rom : std_logic_vector(7 downto 0); type state is (addr0, addr1); signal st : state; ---------- rom_inst : rom port map ( address => addr_rom, clock => clock, q => data_out_rom ); process(reset, clock) begin if reset = '1' then st <= addr0; elsif rising_edge(clock) then case st is when addr0 => addr_rom <= "00000"; ver(15 downto 8) <= data_out_rom; st <= addr1; when addr1 => addr_rom <= "00001"; ver(7 downto 0) <= data_out_rom; st <= addr0; when others => st <= addr0; end case; end if; end process;
Best, Jamesprocess(all) variable addr : natural range 0 to NUM_PARAMS; begin if HRST then param1 <= (others => '0'); param2 <= (others => '0'); param3 <= (others => '0'); elsif rising_edge(MCLK) then case state is when S0 => if Update then state <= S1; else state <= S0; end if; addr := 0; when S1 => addr := addr + 1; state <= S2; when S2 => param1 <= coeffData; (This would come from your ROM that you instantiate) state <= S3; when S3 => addr := addr + 1; state <= S4; when S4 => param2 <= coeffData; state <= S5; when S5 => addr := addr + 1; state <= S6; when S6 => param3 <= coeffData; and so on . . . . - Altera_Forum
Honored Contributor
I'm trying to create a code that can show the VHDL firmware version, like everytime someone changes a firmware, the version changes, and that version number is in a txt file, so the VHDL code I am trying to make, it reads those numbers and everytime the code is compiled it contains the new firmware version.
So in order for me to do that, I figured I would use a ROM to hold that information in the FPGA.