Code Monkey home page Code Monkey logo

Comments (9)

daveshah1 avatar daveshah1 commented on July 18, 2024

May not help much, but I know it worked around July, probably LiteX revision f4770219 or so

from litex-boards.

enjoy-digital avatar enjoy-digital commented on July 18, 2024

@daveshah1: thanks, we'll get back to that is we don't get it working easily.
@piotr-binkowski: can you do a test with ddram_64 and provide the Write/Read leveling logs? The automatic write leveling needs to be improved and still requires some manual adjustments on some configs.

from litex-boards.

enjoy-digital avatar enjoy-digital commented on July 18, 2024

#54 (comment) could also be useful to debug the ZCU104 with 64-bit.

from litex-boards.

enjoy-digital avatar enjoy-digital commented on July 18, 2024

@piotr-binkowski: 75286f8 adds a missing INTERNAL VREF on Bank 64:

image

This probably explains why only half of the modules were working. Can you do a test with this?

If this is not working, can you do another test with cmd_latency set to 0?

from litex-boards.

piotr-binkowski avatar piotr-binkowski commented on July 18, 2024

@enjoy-digital I did the tests but it looks like LiteDRAM still has problems with read leveling
With cmd_latency set to 1 I get:

--=============== SoC ==================--
CPU:       VexRiscv @ 125MHz
ROM:       32KB
SRAM:      4KB
L2:        8KB
MAIN-RAM:  1048576KB

--========== Initialization ============--
Initializing SDRAM...
SDRAM now under software control
Write leveling:
m0: |1110000000000000000001| delay: 00
m1: |1110000000000000000001| delay: 00
m2: |1111000000000000000000| delay: 00
m3: |1111100000000000000000| delay: 00
m4: |1111111100000000000000| delay: 00
m5: |1111111000000000000000| delay: 00
m6: |1111111111000000000000| delay: 00
m7: |1111111000000000000000| delay: 00
Read leveling:
m0, b0: |00000000000000000000000000000000| delays: -
m0, b1: |00000000000000000000000000000000| delays: -
m0, b2: |11000000000000000000000000000000| delays: 13+-13
m0, b3: |00000000000000000000000000000000| delays: -
m0, b4: |00000000000000000000000000000000| delays: -
m0, b5: |00000000000000000000000000000000| delays: -
m0, b6: |00000000000000000000000000000000| delays: -
m0, b7: |00000000000000000000000000000000| delays: -
best: m0, b2 delays: 13+-13
m1, b0: |00000000000000000000000000000000| delays: -
m1, b1: |00000000000000000000000000000000| delays: -
m1, b2: |11000000000000000000000000000000| delays: 11+-11
m1, b3: |00000000000000000000000000000000| delays: -
m1, b4: |00000000000000000000000000000000| delays: -
m1, b5: |00000000000000000000000000000000| delays: -
m1, b6: |00000000000000000000000000000000| delays: -
m1, b7: |00000000000000000000000000000000| delays: -
best: m1, b2 delays: 11+-11
m2, b0: |00000000000000000000000000000000| delays: -
m2, b1: |00000000000000000000000000000000| delays: -
m2, b2: |00000000000000000000000000000000| delays: -
m2, b3: |11111111111111111100000000000000| delays: 08+-08
m2, b4: |00000000000000000000000000000000| delays: -
m2, b5: |00000000000000000000000000000000| delays: -
m2, b6: |00000000000000000000000000000000| delays: -
m2, b7: |00000000000000000000000000000000| delays: -
best: m2, b3 delays: 08+-08
m3, b0: |00000000000000000000000000000000| delays: -
m3, b1: |00000000000000000000000000000000| delays: -
m3, b2: |00000000000000000000000000000000| delays: -
m3, b3: |00000000000000000000000000000000| delays: -
m3, b4: |00000000000000000000000000000000| delays: -
m3, b5: |00000000000000000000000000000000| delays: -
m3, b6: |00000000000000000000000000000000| delays: -
m3, b7: |00000000000000000000000000000000| delays: -
best: m3, b0 delays: -
m4, b0: |00000000000000000000000000000000| delays: -
m4, b1: |00000000000000000000000000000000| delays: -
m4, b2: |00000000000000000000000000000000| delays: -
m4, b3: |11111111111111100000000000000000| delays: 109+-109
m4, b4: |00000000000000000000000000000000| delays: -
m4, b5: |00000000000000000000000000000000| delays: -
m4, b6: |00000000000000000000000000000000| delays: -
m4, b7: |00000000000000000000000000000000| delays: -
best: m4, b3 delays: 114+-114
m5, b0: |00000000000000000000000000000000| delays: -
m5, b1: |00000000000000000000000000000000| delays: -
m5, b2: |00000000000000000000000000000000| delays: -
m5, b3: |11111111111110000000000000000000| delays: 104+-104
m5, b4: |00000000000000000000000000000000| delays: -
m5, b5: |00000000000000000000000000000000| delays: -
m5, b6: |00000000000000000000000000000000| delays: -
m5, b7: |00000000000000000000000000000000| delays: -
best: m5, b3 delays: 104+-104
m6, b0: |00000000000000000000000000000000| delays: -
m6, b1: |00000000000000000000000000000000| delays: -
m6, b2: |00000000000000000000000000000000| delays: -
m6, b3: |11111111111000000000000000000000| delays: 86+-86
m6, b4: |00000000000001111111111111111100| delays: 328+-138
m6, b5: |00000000000000000000000000000001| delays: 497+-14
m6, b6: |00000000000000000000000000000000| delays: -
m6, b7: |00000000000000000000000000000000| delays: -
best: m6, b4 delays: 328+-136
m7, b0: |00000000000000000000000000000000| delays: -
m7, b1: |00000000000000000000000000000000| delays: -
m7, b2: |00000000000000000000000000000000| delays: -
m7, b3: |11111111110000000000000000000000| delays: 71+-71
m7, b4: |00000000000000000000000000000000| delays: -
m7, b5: |00000000000000000000000000000000| delays: -
m7, b6: |00000000000000000000000000000000| delays: -
m7, b7: |00000000000000000000000000000000| delays: -
best: m7, b3 delays: 71+-71
SDRAM now under hardware control
Memtest bus failed: 48/256 errors
Memtest data failed: 392743/524288 errors
Memory initialization failed

And with it set to 0:

--=============== SoC ==================--
CPU:       VexRiscv @ 125MHz
ROM:       32KB
SRAM:      4KB
L2:        8KB
MAIN-RAM:  1048576KB

--========== Initialization ============--
Initializing SDRAM...
SDRAM now under software control
Write leveling:
m0: |1110000000000000000001| delay: 00
m1: |1110000000000000000001| delay: 00
m2: |1111000000000000000000| delay: 00
m3: |1111100000000000000000| delay: 00
m4: |1111111100000000000000| delay: 00
m5: |1111111000000000000000| delay: 00
m6: |1111111111000000000000| delay: 00
m7: |1111111000000000000000| delay: 00
Read leveling:
m0, b0: |00000000000000000000000000000000| delays: -
m0, b1: |00000000000000000000000000000000| delays: -
m0, b2: |00000000000000000000000000000000| delays: -
m0, b3: |00000000000000000000000000000000| delays: -
m0, b4: |00000000000000000000000000000000| delays: -
m0, b5: |00000000000000000000000000000000| delays: -
m0, b6: |00000000000000000000000000000000| delays: -
m0, b7: |00000000000000000000000000000000| delays: -
best: m0, b0 delays: -
m1, b0: |00000000000000000000000000000000| delays: -
m1, b1: |00000000000000000000000000000000| delays: -
m1, b2: |00000000000000000000000000000000| delays: -
m1, b3: |00000000000000000000000000000000| delays: -
m1, b4: |00000000000000000000000000000000| delays: -
m1, b5: |00000000000000000000000000000000| delays: -
m1, b6: |00000000000000000000000000000000| delays: -
m1, b7: |00000000000000000000000000000000| delays: -
best: m1, b0 delays: -
m2, b0: |00000000000000000000000000000000| delays: -
m2, b1: |00000000000000000000000000000000| delays: -
m2, b2: |00000000000000000000000000000000| delays: -
m2, b3: |00000000000000000000000000000000| delays: -
m2, b4: |00000000000000000000000000000000| delays: -
m2, b5: |00000000000000000000000000000000| delays: -
m2, b6: |00000000000000000000000000000000| delays: -
m2, b7: |00000000000000000000000000000000| delays: -
best: m2, b0 delays: -
m3, b0: |00000000000000000000000000000000| delays: -
m3, b1: |00000000000000000000000000000000| delays: -
m3, b2: |00000000000000000000000000000000| delays: -
m3, b3: |00000000000000000000000000000000| delays: -
m3, b4: |00000000000000000000000000000000| delays: -
m3, b5: |00000000000000000000000000000000| delays: -
m3, b6: |00000000000000000000000000000000| delays: -
m3, b7: |00000000000000000000000000000000| delays: -
best: m3, b0 delays: -
m4, b0: |00000000000000000000000000000000| delays: -
m4, b1: |00000000000000000000000000000000| delays: -
m4, b2: |00000000000000000000000000000000| delays: -
m4, b3: |00000000000000000000000000000000| delays: -
m4, b4: |00000000000000000000000000000000| delays: -
m4, b5: |00000000000000000000000000000000| delays: -
m4, b6: |00000000000000000000000000000000| delays: -
m4, b7: |00000000000000000000000000000000| delays: -
best: m4, b0 delays: -
m5, b0: |00000000000000000000000000000000| delays: -
m5, b1: |00000000000000000000000000000000| delays: -
m5, b2: |00000000000000000000000000000000| delays: -
m5, b3: |00000000000000000000000000000000| delays: -
m5, b4: |00000000000000000000000000000000| delays: -
m5, b5: |00000000000000000000000000000000| delays: -
m5, b6: |00000000000000000000000000000000| delays: -
m5, b7: |00000000000000000000000000000000| delays: -
best: m5, b0 delays: -
m6, b0: |00000000000000000000000000000000| delays: -
m6, b1: |00000000000000000000000000000000| delays: -
m6, b2: |00000000000000000000000000000000| delays: -
m6, b3: |00000000000000000000000000000000| delays: -
m6, b4: |00000000000000000000000000000000| delays: -
m6, b5: |00000000000000000000000000000000| delays: -
m6, b6: |00000000000000000000000000000000| delays: -
m6, b7: |00000000000000000000000000000000| delays: -
best: m6, b0 delays: -
m7, b0: |00000000000000000000000000000000| delays: -
m7, b1: |00000000000000000000000000000000| delays: -
m7, b2: |00000000000000000000000000000000| delays: -
m7, b3: |00000000000000000000000000000000| delays: -
m7, b4: |00000000000000000000000000000000| delays: -
m7, b5: |00000000000000000000000000000000| delays: -
m7, b6: |00000000000000000000000000000000| delays: -
m7, b7: |00000000000000000000000000000000| delays: -
best: m7, b0 delays: -
SDRAM now under hardware control
Memtest bus failed: 96/256 errors
Memtest data failed: 524281/524288 errors
Memtest addr failed: 5120/8192 errors
Memory initialization failed

from litex-boards.

enjoy-digital avatar enjoy-digital commented on July 18, 2024

@piotr-binkowski: thanks for the tests. The issue seems to be on write leveling. We need to center it. I need to do more tests on the board i have to be sure we are able to center it on Ultrascale(+) (the last time i tried it was not behaving correctly).

from litex-boards.

enjoy-digital avatar enjoy-digital commented on July 18, 2024

@piotr-binkowski: with 555bf6c, you will now have additional debug commands available in the BIOS:

sdram_cdly value                - Set SDRAM clk/cmd delay
sdram_cal                       - run SDRAM calibration
sdram_mpr                       - read SDRAM MPR
sdram_mrwr reg value            - write SDRAM mode registers

I think the issue in your case is that the software needs some help to be able to do the write leveling correctly. Here is for example the default write leveling on the KCU105:

Write leveling:
m0: |00000001111111111111100000| delay: 111
m1: |00000000111111111111100000| delay: 117
m2: |00000000001111111111111000| delay: 147
m3: |00000000000111111111111100| delay: 164
m4: |00000000000011111111111110| delay: 184
m5: |00000000000011111111111110| delay: 189
m6: |00000000000001111111111111| delay: 200
m7: |10000000000001111111111111| delay: 199

vs the one you have on the ZCU104:

Write leveling:
m0: |1110000000000000000001| delay: 00
m1: |1110000000000000000001| delay: 00
m2: |1111000000000000000000| delay: 00
m3: |1111100000000000000000| delay: 00
m4: |1111111100000000000000| delay: 00
m5: |1111111000000000000000| delay: 00
m6: |1111111111000000000000| delay: 00
m7: |1111111000000000000000| delay: 00

We need to help the software by adding delay to clk/cmd going to the DDR4 to allow it to do a proper write leveling (in the future we could try to automate this, but for now this not the case).

On the KCU105, when adding 128 taps of delay to the clk/cmd with:

litex> sdram_cdly 128
Setting clk/cmd delay to 128 taps

We see that the write leveling is shifted by the number of taps:

litex> sdram_cal
SDRAM now under software control
Write leveling:
m0: |11100000000000011111111111| delay: 237
m1: |11110000000000001111111111| delay: 245
m2: |11111000000000000111111111| delay: 272
m3: |11111100000000000001111111| delay: 290
m4: |11111110000000000000111111| delay: 00
m5: |11111111000000000000111111| delay: 00
m6: |11111111000000000000011111| delay: 00
m7: |11111111000000000000011111| delay: 00

On the ZCU104, can you play with sdram_cdly x and sdram_cal commands to try to allow the write leveling software to see the full ones window (or the best it is possible) and see with sdram_cal if it improves the calibration?

If you are not able to get it working, can you post the results here? Once we'll know how much clk/cmd delay is needed, we could specificy it in the target file with: self.add_constant("DDRPHY_CMD_DELAY", X)

from litex-boards.

piotr-binkowski avatar piotr-binkowski commented on July 18, 2024

I did some tests on the ZCU104 but this time it was equipped with the MTA4ATF51264HZ SO-DIMM module. It appears that this module has no problems with read and write leveling and even passes the memtest using full 64-bit data bus.

Write leveling:
m0: |1110000000000000000001| delay: 00
m1: |1110000000000000000011| delay: 00
m2: |1111000000000000000000| delay: 00
m3: |1111100000000000000000| delay: 00
m4: |1111111100000000000000| delay: 00
m5: |1111111100000000000000| delay: 00
m6: |1111111111000000000000| delay: 00
m7: |1111111000000000000000| delay: 00
Read leveling:
m0, b0: |00000000000000000000000000000000| delays: -
m0, b1: |00000000000000000000000000000000| delays: -
m0, b2: |11000000000000000000000000000000| delays: 14+-14
m0, b3: |00001111111111111111000000000000| delays: 183+-132
m0, b4: |00000000000000000000001111111111| delays: 429+-83
m0, b5: |00000000000000000000000000000000| delays: -
m0, b6: |00000000000000000000000000000000| delays: -
m0, b7: |00000000000000000000000000000000| delays: -
best: m0, b3 delays: 184+-132
m1, b0: |00000000000000000000000000000000| delays: -
m1, b1: |00000000000000000000000000000000| delays: -
m1, b2: |11000000000000000000000000000000| delays: 14+-14
m1, b3: |00001111111111111111000000000000| delays: 186+-131
m1, b4: |00000000000000000000001111111111| delays: 429+-83
m1, b5: |00000000000000000000000000000000| delays: -
m1, b6: |00000000000000000000000000000000| delays: -
m1, b7: |00000000000000000000000000000000| delays: -
best: m1, b3 delays: 185+-132
m2, b0: |00000000000000000000000000000000| delays: -
m2, b1: |00000000000000000000000000000000| delays: -
m2, b2: |00000000000000000000000000000000| delays: -
m2, b3: |01111111111111111100000000000000| delays: 139+-136
m2, b4: |00000000000000000001111111111111| delays: 406+-106
m2, b5: |00000000000000000000000000000000| delays: -
m2, b6: |00000000000000000000000000000000| delays: -
m2, b7: |00000000000000000000000000000000| delays: -
best: m2, b3 delays: 141+-137
m3, b0: |00000000000000000000000000000000| delays: -
m3, b1: |00000000000000000000000000000000| delays: -
m3, b2: |00000000000000000000000000000000| delays: -
m3, b3: |01111111111111111100000000000000| delays: 147+-136
m3, b4: |00000000000000000000111111111111| delays: 407+-104
m3, b5: |00000000000000000000000000000000| delays: -
m3, b6: |00000000000000000000000000000000| delays: -
m3, b7: |00000000000000000000000000000000| delays: -
best: m3, b3 delays: 147+-136
m4, b0: |00000000000000000000000000000000| delays: -
m4, b1: |00000000000000000000000000000000| delays: -
m4, b2: |00000000000000000000000000000000| delays: -
m4, b3: |11111111111111000000000000000000| delays: 111+-111
m4, b4: |00000000000000001111111111111111| delays: 381+-131
m4, b5: |00000000000000000000000000000000| delays: -
m4, b6: |00000000000000000000000000000000| delays: -
m4, b7: |00000000000000000000000000000000| delays: -
best: m4, b4 delays: 381+-131
m5, b0: |00000000000000000000000000000000| delays: -
m5, b1: |00000000000000000000000000000000| delays: -
m5, b2: |00000000000000000000000000000000| delays: -
m5, b3: |11111111111111000000000000000000| delays: 105+-105
m5, b4: |00000000000000011111111111111111| delays: 368+-131
m5, b5: |00000000000000000000000000000000| delays: -
m5, b6: |00000000000000000000000000000000| delays: -
m5, b7: |00000000000000000000000000000000| delays: -
best: m5, b4 delays: 370+-132
m6, b0: |00000000000000000000000000000000| delays: -
m6, b1: |00000000000000000000000000000000| delays: -
m6, b2: |00000000000000000000000000000000| delays: -
m6, b3: |11111111111100000000000000000000| delays: 89+-89
m6, b4: |00000000000001111111111111111100| delays: 332+-136
m6, b5: |00000000000000000000000000000001| delays: 500+-12
m6, b6: |00000000000000000000000000000000| delays: -
m6, b7: |00000000000000000000000000000000| delays: -
best: m6, b4 delays: 330+-135
m7, b0: |00000000000000000000000000000000| delays: -
m7, b1: |00000000000000000000000000000000| delays: -
m7, b2: |00000000000000000000000000000000| delays: -
m7, b3: |11111111110000000000000000000000| delays: 72+-72
m7, b4: |00000000000111111111111111110000| delays: 300+-132
m7, b5: |00000000000000000000000000000111| delays: 485+-26
m7, b6: |00000000000000000000000000000000| delays: -
m7, b7: |00000000000000000000000000000000| delays: -
best: m7, b4 delays: 301+-133
SDRAM now under hardware control
Memtest OK
Memspeed Writes: 458Mbps Reads: 524Mbps

And this is how the training looks like with sdram_cdly 128

litex> sdram_cdly 128
Setting clk/cmd delay to 128 taps
litex> sdram_cal
SDRAM now under software control
Write leveling:
m0: |1111111111100000000000| delay: 00
m1: |1111111111100000000000| delay: 00
m2: |1111111111111000000000| delay: 00
m3: |1111111111111000000000| delay: 00
m4: |1111111111111111000000| delay: 00
m5: |1111111111111111000000| delay: 00
m6: |1111111111111111110000| delay: 00
m7: |1111111111111110000000| delay: 00
Read leveling:
m0, b0: |00000000000000000000000000000000| delays: -
m0, b1: |00000000000000000000000000000000| delays: -
m0, b2: |00000000000000000000000000000000| delays: -
m0, b3: |11111111111100000000000000000000| delays: 93+-93
m0, b4: |00000000000000111111111111111100| delays: 346+-130
m0, b5: |00000000000000000000000000000000| delays: 519+-08
m0, b6: |00000000000000000000000000000000| delays: -
m0, b7: |00000000000000000000000000000000| delays: -
best: m0, b4 delays: 347+-130
m1, b0: |00000000000000000000000000000000| delays: -
m1, b1: |00000000000000000000000000000000| delays: -
m1, b2: |00000000000000000000000000000000| delays: -
m1, b3: |11111111111100000000000000000000| delays: 94+-94
m1, b4: |00000000000000111111111111111110| delays: 346+-132
m1, b5: |00000000000000000000000000000000| delays: 516+-08
m1, b6: |00000000000000000000000000000000| delays: -
m1, b7: |00000000000000000000000000000000| delays: -
best: m1, b4 delays: 347+-131
m2, b0: |00000000000000000000000000000000| delays: -
m2, b1: |00000000000000000000000000000000| delays: -
m2, b2: |00000000000000000000000000000000| delays: -
m2, b3: |11111111110000000000000000000000| delays: 72+-72
m2, b4: |00000000000111111111111111110000| delays: 303+-133
m2, b5: |00000000000000000000000000000111| delays: 487+-25
m2, b6: |00000000000000000000000000000000| delays: -
m2, b7: |00000000000000000000000000000000| delays: -
best: m2, b4 delays: 303+-132
m3, b0: |00000000000000000000000000000000| delays: -
m3, b1: |00000000000000000000000000000000| delays: -
m3, b2: |00000000000000000000000000000000| delays: -
m3, b3: |11111111110000000000000000000000| delays: 76+-76
m3, b4: |00000000000111111111111111110000| delays: 313+-135
m3, b5: |00000000000000000000000000000011| delays: 489+-23
m3, b6: |00000000000000000000000000000000| delays: -
m3, b7: |00000000000000000000000000000000| delays: -
best: m3, b4 delays: 310+-136
m4, b0: |00000000000000000000000000000000| delays: -
m4, b1: |00000000000000000000000000000000| delays: -
m4, b2: |00000000000000000000000000000000| delays: -
m4, b3: |11111100000000000000000000000000| delays: 46+-46
m4, b4: |00000000111111111111111110000000| delays: 252+-135
m4, b5: |00000000000000000000000000111111| delays: 461+-50
m4, b6: |00000000000000000000000000000000| delays: -
m4, b7: |00000000000000000000000000000000| delays: -
best: m4, b4 delays: 253+-135
m5, b0: |00000000000000000000000000000000| delays: -
m5, b1: |00000000000000000000000000000000| delays: -
m5, b2: |00000000000000000000000000000000| delays: -
m5, b3: |11111000000000000000000000000000| delays: 40+-40
m5, b4: |00000001111111111111111100000000| delays: 239+-131
m5, b5: |00000000000000000000000000111111| delays: 457+-55
m5, b6: |00000000000000000000000000000000| delays: -
m5, b7: |00000000000000000000000000000000| delays: -
best: m5, b4 delays: 240+-133
m6, b0: |00000000000000000000000000000000| delays: -
m6, b1: |00000000000000000000000000000000| delays: -
m6, b2: |00000000000000000000000000000000| delays: -
m6, b3: |11100000000000000000000000000000| delays: 23+-23
m6, b4: |00000111111111111111110000000000| delays: 203+-135
m6, b5: |00000000000000000000000111111111| delays: 436+-75
m6, b6: |00000000000000000000000000000000| delays: -
m6, b7: |00000000000000000000000000000000| delays: -
best: m6, b4 delays: 203+-135
m7, b0: |00000000000000000000000000000000| delays: -
m7, b1: |00000000000000000000000000000000| delays: -
m7, b2: |00000000000000000000000000000000| delays: -
m7, b3: |10000000000000000000000000000000| delays: 08+-08
m7, b4: |00011111111111111111000000000000| delays: 172+-130
m7, b5: |00000000000000000000011111111111| delays: 420+-91
m7, b6: |00000000000000000000000000000000| delays: -
m7, b7: |00000000000000000000000000000000| delays: -
best: m7, b4 delays: 173+-130
SDRAM now under hardware control

I will prepare a PR that makes ZCU104 use that module and we can look into improving the write leveling situation in the future.
Or do you prefer to do this in a different way? @enjoy-digital

from litex-boards.

enjoy-digital avatar enjoy-digital commented on July 18, 2024

Great, i think i would also have worked with sdram_cdly and the previous SO-DIMM. Xilinx seems to recommend a MTA8ATF51264HZ SO-DIMM on this board which probably as timings closer to the MTA4ATF51264HZ than the Kingston SO-DIMM, so let's use this and we could still adjust the timing in the future if the SO-DIMM is changed.

from litex-boards.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.