Hi everyone, I want to write an VHDL SDRAM controller for IS42S16160B-7 32MB SDRAM chip that comes with Terasic DE0-nano FPGA board. First of all, i tried to look at some codes that developed for that purpose, the interesting one was the Hamster code: http://hamsterworks.co.nz/mediawiki/index.php/SDRAM_Memory_Controller But i didn't understand the use of the counter used to make initialization, and also the different values of it. I would like to know if anyone has an idea please. Thanks in advance. Best Regards
I'm not sure if you mean "init_counter", if yes: it ensures the correct initialization, which requires a minimum of e.g. 100us. This detail is specified in the related datasheet and ensures that the related pll, sdram's internal controller etc. runs stable.
And btw.: if this is your first controller, start with hamster's first approach, it's very simple to implement and it's used in several projects.
Thanks Sigi, Yes, it's my first controller. What i don't understand is this part of code:
signal r : reg := ((others => '0'), (others => '0'), (others => '0'), "000000000001000", (others => '0'), '0', '0', '0', (others => '0'), (others => '0'), '0', (others => '0'));
specially the value of "000000000001000", it doesn't correspond to 100us minimum "init_counter"
And also this part of code:
n.init_counter <= r.init_counter-1; -- Process the FSM case r.state(8 downto 4) is when s_init_nop(8 downto 4) => n.state <= s_init_nop; n.address <= (others => '0'); n.bank <= (others => '0'); n.rf_counter <= (others => '0'); n.data_out_valid <= '1'; -- T-130, precharge all banks. if r.init_counter = "000000010000010" then n.state <= s_init_pre; n.address(10) <= '1'; end if; -- T-127, T-111, T-95, T-79, T-63, T-47, T-31, T-15, the 8 refreshes if r.init_counter(14 downto 7) = 0 and r.init_counter(3 downto 0) = 15 then n.state <= s_init_ref; end if; -- T-3, the load mode register if r.init_counter = 3 then n.state <= s_init_mrs; -- Mode register is as follows: -- resvd wr_b OpMd CAS=3 Seq bust=4 n.address <= "000" & "0" & "00" & "011" & "0" & "010"; -- resvd n.bank <= "00"; end if; -- T-1 The switch to the FSM (first command will be a NOP if r.init_counter = 1 then n.state <= s_idle; end if;
I I understand, the "init_counter" value must be: initialization time(100us for example) + tRP(precharge time)+ tRC(auto refresh time)+tMRD(mode register time). Best regards
Hi, yesterday I spent only few minutes to roughly understand the different approaches and I thought/allready think they are more or less easy to understand. And I spent only ~10 seconds to find your initial signal, without trying to understand the code completely. So, after taking a deeper look into the code, my opinion is now: "Ok Jesus, this is rocket science, hard to understand". (init_counter is init with value 8, and then compared with value 130 ??, this makes no sense, there is nothing like "wait for 100 us" ??) My advice is: Take the first approach as inspiration, download a good datasheet from eg MICRON (MT48LC4M32B2.pdf) and start with your own design. All the essential parts (Init, Read, Write, Active, Precharge, Refresh) are "linear", so they are easy to map into a simple FSM. Then download the verilog/VHDL design of the SDRAM and check with a simple testbench the correctness. (or try to find a "good" SDRAM-controller, a good starting point are the classic computing designs like MiniMIG, AtariST etc., almost all 16Bit Computer Designs uses SDRAMs)
Thank you for you advice.