OpenCores
Issue List
Plasma at 50 Mhz or More #13
Open moodz opened this issue about 14 years ago
moodz commented about 14 years ago

Quick Howto 1. Change ALU from "DEFAULT" to something like "OPTIMISED" in mlite_pack.vhd 2. Changed this bit of code in pc_next.vhd ( compare to original ) if reset_in = '1' then pc_reg <= ZERO(31 downto 2); pc_next := ZERO(31 downto 2); elsif rising_edge(clk) then pc_reg <= pc_next; end if; 3. set clk_reg <= CLK_50MHZ

  1. Create a new signal called clk_div2 and set it to the original 25 Mhz ... feed to DDR2.
  2. Set pipeline = 3, ethernet and cache enabled.

  3. Enjoy.

My compilation results on 11.1 ISE indicate a maximum clock rate of 93.39 Mhz .... WOW :-0

moodz commented about 14 years ago

Tested on S3E500 starter kit with bootloader, count, opcodetest etc all OK.

theshadowx commented about 14 years ago

i'll try that i need it to make vga work perfectly as i need at least 25Mhz

thanks Paul

moodz commented about 14 years ago

Ali ... your commments appear blank.

theshadowx commented about 14 years ago

i don't know what s happening i ve commented once.

i have just one question, how could it be 93.93 Mhz if the main clock is 50 MHz,

Does you're method take count of the fall and rise of the same period of the clock ?

moodz commented about 14 years ago

Hi Ali, the 93 MHz is an estimate by the synthesis based on theoretical path delays in the chip. It is meant to provide some guidance as to how much headroom your actual design clock has .. in this case the SOC I run using a plasma is very stable at 50 Mhz the DDR is clocked at 100 Mhz. See my project at http://www.geotech1.com/forums/showthread.php?p=109020#post109020

theshadowx commented about 14 years ago

Hi Paul thanks for you explanation.

i have something that bother me a lot, is that when i write a C code program for example a clock.

each second a led light up

the problem is that the counter should be done as if the clock is 12.5 MHz and not 25 MHz

so for one second i have to count until 12500000 and not 25000000

Is it normal or something wrong

Ali

orinaudo commented almost 14 years ago

could you please elaborate ? if the core runs at 50Mhz, ddr need 100MHz u need a frequence doubler unless a 100MHz clock is added (CLK_AUX) or a DCM is used ?

Thanks & Regards OR

moodz commented almost 14 years ago

Well at first when I clocked the CPU up to 50 Mhz I could not get the DDR to run properly so it was running at 50 Mhz with wait states. I played with the adress decoding which seemed to be a bit flakey and I now clock the DDR with 100 Mhz from a DCM. It seems to pass the memory testing code OK however I have not loaded anything serious into it because I have been busy gluing the Alternascope ( see project list ) onto the plasma. The plasma now has VDU and 4 channel scope / waveform display from VGA port on spartan 3e starter board. It is a sort of DSP explorer with visualisation.

Paul.

orinaudo commented almost 14 years ago

Hi,

plateform is sp3e1600 with ISE WEB 12.1 as discussed i've added dcm to create 100Mhz clock , changes (in plasma3e.vhd only) as follow :

:signal list :

  • signal clk_d100mhz : std_logic; --dcm clock
  • signal dcm_gnd_bit : std_logic;

begin --architecture -- dcm
dcm_gnd_bit <= '0';

--clk_d100_bufg : BUFG --port map (I=>clk_d100mhz_buf, -- O=>clk_d100mhz);

--clk_reg_bufg : BUFG --port map (I=>clk_reg_buf, -- O=>clk_reg);

DCM_SP_INST : DCM_SP generic map( CLK_FEEDBACK => "2X", CLKDV_DIVIDE => 2.0, CLKFX_DIVIDE => 1, CLKFX_MULTIPLY => 4, --not used CLKIN_DIVIDE_BY_2 => FALSE, CLKIN_PERIOD => 20.000, --50Mhz CLKOUT_PHASE_SHIFT => "NONE", DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS", DFS_FREQUENCY_MODE => "LOW", DLL_FREQUENCY_MODE => "LOW", DUTY_CYCLE_CORRECTION => TRUE, FACTORY_JF => x"C080", PHASE_SHIFT => 0, STARTUP_WAIT => FALSE) port map (CLKFB=>clk_d100mhz, CLKIN=>CLK_50MHZ, DSSEN=>dcm_gnd_bit, PSCLK=>dcm_gnd_bit, PSEN=>dcm_gnd_bit, PSINCDEC=>dcm_gnd_bit, RST=>reset, CLKDV=>open, CLKFX=>open, CLKFX180=>open, CLK0=>open, CLK2X=>clk_d100mhz, CLK2X180=>open, CLK90=>open, CLK180=>open, CLK270=>open, LOCKED=>open, PSDONE=>open, STATUS=>open);

and then use signal clk_d100mhz instead of CLK_50MHZ

1°) in a first attempt i tried to use BUFG as generated by the wizard and to use the CLK0 output from the DCM in order to have (as per my understanding of the docs) better sync between 100 & 50 Mhz clocks -> timing where not reached

2°)then i removed BUFG and enabled again the clk_div as per initial implementation

-> compiling was OK -> bootldr.c started ok (as expected, it was necessary to switch speed of serial console to 115200 instead of 57600) and then adjust uart.vhd to get back to 57600

but making a simple DDR RAM test writing paterns to ram then reading them -> i got many errors, writing 0xFF then just after reading other value

i tried to tweak a little bit the ddr_init.c to change delays during ram initialization ie :

line 54: for(j = 0; j < 4; ++j) changed to 4 to 8

line 57: for(j = 0; j < 100; ++j) change 100 to 200

as per j micron doc (pg 52) some delays are requested between init sequences.

also tried to add some additionnal NOP during init as follow :

(0x400 << 13) | (0 << 11) | (2 << 4), //A10=1; PRECHARGE ALL="010" //wait 15ns min // (0x000 << 13) | (0 << 11) | (7 << 4), //CKE=1; NOP="111" //one more NOP #ifndef DLL_DISABLE (0x000 << 13) | (1 << 11) | (0 << 4), //enable DLL; BA="01"; LMR="000" //wait 12ns min #else (0x001 << 13) | (1 << 11) | (0 << 4), //disable DLL; BA="01"; LMR="000" //wait 12ns min #endif // (0x000 << 13) | (0 << 11) | (7 << 4), //CKE=1; NOP="111" //one more NOP (0x121 << 13) | (0 << 11) | (0 << 4), //reset DLL, CL=2, BL=2; LMR="000" //wait 12ns min // (0x000 << 13) | (0 << 11) | (7 << 4), //CKE=1; NOP="111" //one more NOP (0x400 << 13) | (0 << 11) | (2 << 4), //A10=1; PRECHARGE ALL="010" //wait 15ns min // (0x000 << 13) | (0 << 11) | (7 << 4), //CKE=1; NOP="111" //one more NOP (0x000 << 13) | (0 << 11) | (1 << 4), //AUTO REFRESH="001" //wait 72ns min // (0x000 << 13) | (0 << 11) | (7 << 4), //CKE=1; NOP="111" //one more NOP (0x000 << 13) | (0 << 11) | (1 << 4), //AUTO REFRESH="001 //wait 72ns min (0x021 << 13) | (0 << 11) | (0 << 4) //clear DLL, CL=2, BL=2; LMR="000"

without success. finally i tried to set CAS from 2 to 2.5 but this may require to change .vhd accordingly and jmicon doc indicate CAS2 is ok up to 133 Mhz

any higlight appreciated .

Thanks & Regards OR

moodz commented almost 14 years ago

What I did was to generate the 100 Meg clock_x2 using DCM to feed the DDR ... The plasma clock is derived from the 100 meg clock.. below is the 50 meg clock generator.

--Divide clock by two clk_div: process(reset, clk_reg, clk_x2) begin if reset = '1' then clk_reg <= '0'; elsif rising_edge(clk_x2) then clk_reg <= not clk_reg; end if; end process; --clk_div

you should also configure this bit as follows in mlite_pack.vhd otherwise the CPU may be unstable at 50 mhz.

component mlite_cpu generic(memory_type : string := "XILINX_16X"; mult_type : string := "DEFAULT"; shifter_type : string := "OPTIMISED"; alu_type : string := "OPTIMISED"; pipeline_stages : natural := 3); --2 or 3

orinaudo commented almost 14 years ago

Thanks for your feed back, with internal ram it run but i still have random issues when accessing ddr (1MB read/write patterns tests) Regards OR

moodz commented almost 14 years ago

The original address in the top module is not optimal. Try this .... obviously I decode some extra things just comment them out.

-----------address decoding------------------ sync_decode: process(reset, clk_reg, ddr_active, flash_active, video_active,wform_active, write_enable) begin if rising_edge(clk_reg) then if address(31 downto 28) = "0001" then ddr_active <= '1'; flash_active <= '0'; video_active <= '0'; wform_active <= '0'; elsif address(31 downto 28) = "0011" then ddr_active <= '0'; flash_active <= '1'; video_active <= '0'; wform_active <= '0'; elsif address(31 downto 28) = "0101" then ddr_active <= '0'; flash_active <= '0'; video_active <= '1'; wform_active <= '0'; elsif address(31 downto 28) = "1101" then ddr_active <= '0'; flash_active <= '0'; video_active <= '0'; wform_active <= '1'; else ddr_active <= '0'; flash_active <= '0'; video_active <= '0'; wform_active <= '0'; end if; end if;

if byte_we /= "0000" then write_enable <= '1';
	else write_enable <= '0';
end if;

if byte_we /= "0000" then all_byte_we <= "1111";
	else all_byte_we <= "0000";
end if;

end process;
moodz commented almost 14 years ago

The original address in the top module is not optimal. Try this .... obviously I decode some extra things just comment them out.

-----------address decoding------------------ sync_decode: process(reset, clk_reg, ddr_active, flash_active, video_active,wform_active, write_enable) begin if rising_edge(clk_reg) then if address(31 downto 28) = "0001" then ddr_active <= '1'; flash_active <= '0'; video_active <= '0'; wform_active <= '0'; elsif address(31 downto 28) = "0011" then ddr_active <= '0'; flash_active <= '1'; video_active <= '0'; wform_active <= '0'; elsif address(31 downto 28) = "0101" then ddr_active <= '0'; flash_active <= '0'; video_active <= '1'; wform_active <= '0'; elsif address(31 downto 28) = "1101" then ddr_active <= '0'; flash_active <= '0'; video_active <= '0'; wform_active <= '1'; else ddr_active <= '0'; flash_active <= '0'; video_active <= '0'; wform_active <= '0'; end if; end if;

if byte_we /= "0000" then write_enable <= '1';
	else write_enable <= '0';
end if;

if byte_we /= "0000" then all_byte_we <= "1111";
	else all_byte_we <= "0000";
end if;

end process;
BreiZH commented almost 13 years ago

Hello,

Does someone can provide a link to the modified VHDL sources (the ones which work).

Thanks.


Assignee
No one
Labels
Request