GithubHelp home page GithubHelp logo

nxp / i3c-slave-design Goto Github PK

View Code? Open in Web Editor NEW
101.0 101.0 33.0 14.72 MB

MIPI I3C Basic v1.0 communication Slave source code in Verilog with BSD license to support use in sensors and other devices.

License: Other

Verilog 100.00%

i3c-slave-design's People

Contributors

flit avatar pkimelman-nxp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

i3c-slave-design's Issues

Bug in pread in i3c_dma_control module

In the instantiation of the i3c_dma_control module in the i3c_apb_wrapper.v file, line 295 states:
.pread (PSEL|PENA|~PWRITE),// special for re-arm RX

These APB signals should not be ORed but ANDed together:

   .pread           (PSEL&PENA&~PWRITE),// special for re-arm RX

... unless I have misunderstood something.

Basic testbench

Is there is any basic testbench for i3c slave design?

Regards,
Thangaselvam D

Basic testbench

Is there a very basic testbench to simulate the interface?

Autonomous slave, IBI, no MDB, ACK pulse handoff

Hi:
Have you ever test the IBI without MDB condition?
ENA_IBI_MR_HI = 6'b00_0001;//IBI capable
ENA_TIMEC =5'b0_0000;//no Timing control
BCR[2]=0;//no MDB

My task pulls the SDA low 20ns before the (ACK) SCL 0->1 transition, and then keep it High-Z for 20ns when SCL is high.
However, the slave did handoff.

If I set BCR[2]=1, ENA_IBI_MR_HJ=6'b00_0011 and perform the simulation again, correct ACK handoff take places.
DId I miss anything?

Push pull and open drain

Hi,

Could you please tell me how push pull and open drain is managed in I3C slave rtl verilog code?
Please bear with me if its a silly question. As I am new to I3c didn't get much idea about push pull and open drain.

Thanks and Regards,
Mini Jose

I3C Clock frequency

Hi
As per MIPI I3C specification, what are the supported SCL frequencies?

Thanks
Prats

sda_pad_oe

Using the I3C_auton_wrap_full module as the rtl top.

the testcase as follow steps

1. Frist,I assign the static address,

2. then, I send the static address and Read bit.

3. Dut is ack and enter the ST_READ state.It's okay.

4. testbeach send scl,The Dut sda_pad_oe control may have a error direction.

The simulation wave as follows.
image

"i3c_time_control" module is missing

Dear IP owner, when I tried to use i3c_auton_wrapper with "ENA_TIMEC" parameter enabled, which means that I wanted to enable the Timing control/Timestamping feature, it turned out that "i3c_time_control" module is missing, I think that module is necessary for i3c slave timing control, like sc1/sc2/timec_ibi_byte. I'll really appreciate it if you can also include the "i3c_time_control" module in the package, thanks!!!

i3c_autonomous_reg.v

[`UPPER - : 8 ]
The above words appear many times while wreg and wo_regs are assigned. (line 217, 219, 223, 224, 228, 231, 232, 235)

I use 'auton_wrap_full' as my top module. The i3c_autotonomous_reg.v did not pass the ncverilog simulator.
Did I miss anything?

SDA negated prematurely during ACK

The SDA negation by slave for ACK in response to 7'h7E seems to be premature due to the following in i3c_sdr_slave_engine.v. SDA is negated when SCL related to ACK is asserted by the master which causes STOP_r and the state machines returns to state 0. This is for PIN_MODEL=PINM_COMBO.

assign SDA_oe = ...
((state==ST_ACK_NACK) & ack_ok &
(~in_i3c_msg | (~event_drive & (~pin_SCL_in | was_read)))) |

Any insight will be appreciated.

The function of HJ? thank you very much

Hi dear,
Does free version of i3c_slave_design provide the function of HJ?

I try to modify the parameter of ENA_IBI_MR_HJ to 5'b01000, ENA_TIMEC to 6'd0(due to we do not have design of time control).

My test flow is set 1'b1 to address of 0x4 for bit[0] SLVENA, then trigger my master VIP write data to slave by I2C protocol with static address.

Next, I try to set 2'b11 to address of 0xc for bit[1:0] EVENT after my master VIP write data finish and pull stop.

But I found the SDR_hold will pull 1'b1 when I set 2'b11 to address of 0xc for bit[1:0] EVENT, and I can't no see slave design try to issue start.

In my point, I think slave determines that the Bus is idle it may request a start by pulling SDA low after I set 2'b11 to address of 0xc for bit[1:0] EVENT and then issue address of 7'h02 to request a DAA process. In the end turn to master VIP to choose ack/nack the slave request?

Can you please tell me what's wrong with my setting flow? Does anything I misunderstanding? or the free version does not support HJ? Attachment as my waveform shown that time 17164ns issue STOP and Time 22760ns set 2'b11 to address of 0xc for bit[1:0] EVENT, and then SDR_hold pull up, and then never seen slave design try to issue stop...

Thank you very much. many thanks.

b

tSCO should not be 0

Hi, Paul:

Thank you very much for your quick response to my issue #8. Sorry that I didn't follow up early since I didn't have any updated info. I have attached two waveform for this issue.

In previous issue #8, I think the problem was the glitch on the SDA line. After adding some glitch filter, the issue went away. But after debugging more, I think the real problem was the IP using negedge of 8th SCL and posedge of 9th SCL to control the SDA for the ACK and T bits. From I3C basic spec figure 32 and 40, the SLV_SDA should be driving for tSCO time after rising edge of the SCL before releasing it. In the attached file, top waveform, IP logic falsely detected the STOP condition because of this 0 tSCO. On the bottom figure, the other side master can't detect the T bit correctly. By adding delays to SDA both directions in the simulation environment, these two issues will be resolved. I am wondering if this design may cause any issue in real application. Though the pads and wire may contribute some delay, it could be contribute to both SCL and SDA. Is it better to add some logic to control the tSCO in the IP design?

tSCO0.pptx

Thanks,

June

glitch on i3c_data may cause fake clock for clk_SDA

We have hooked up the i3c_slave with denali master. For I3C transfer, NXP I3C can get dynamic address assignment from master. However, while I3C master issues write transaction to NXP I3C slave, I3C slave detects wrong STOP bit. It breaks slave’s FSM and slave can not receive data from master. The issue is on the following code:

always @ (posedge clk_SDA or negedge rst_STOP_n)
if (!rst_STOP_n)
STOP_r <= 1'b0; // cannot be 1 due to any_START
else if (pin_SCL_in & ~SDR_hold) // SDA rise when SCL=high
STOP_r <= 1'b1; // stopped as a "state"

1). rst_STOP_n is stay as 1
2). Clk_SDA is not toggle, stay as 0
3). SDR_hold = 0 so the ~SDR_hold should have no effect in this case.
4). pin_SCL_in changing 0 -> 1 This caused the STOP_r chaning from 0 -> 1

In our case, the “i3c_sda” line is switching to tri-state. At that moment, denali model also switching from driving a weak1 to strong 0:
“sda” line is also pullup on bench to a pullup strength of 1’b1.
Thus it could be the glitch on SDA line causing the fake clock event.
The SDA can be driven by multiple devices. Is there a way to avoid using SDA as clock? Any suggestion if this is a real issue and how to fix it?

Thanks,

June

DFT scan clock

There are flops in the file i3c_auton_wrapper.v that don't receive the scan clock. This is in the "generate" block @ line#367. Part of the problem was fixed by adding a clock mux:
CLOCK_SOURCE_MUX fix_slow_clk(.use_scan_clock(scan_single_clock, .scan_clock(scan_clk), .pin_clock(CLK_SLOW), .clock(CLOCK_SLOW_scan)); and then updating the "always" block connections.
The other flops in error are the syncronizer flops and these were "fixed" with a quick kluge to connect the port"CLK" and "scan_clk" with the same net. This should be permentaly fixed by adding another mux.

CCCs are not being executed

I've run into the problem, that several CCCs are obviously ACKed by the slave, but are not executed, for example GETPID and RSTDAA.

In the screenshot below (all signals directly below Group I3C are taken from the slave IP -sorry for the mess- ; Group Master shows the I3C Master Interface) you can see the command GETPID 0x8D, which is ACKed but only '0' sent as response, although prov_id is definitely assigned. I think I've tracked it down to line 828 in sdr_slave_engine:
wire da_suppress = vgpio_ccc | (in_ccc[0] & ~ccc_uh_mask); // these collapse if not used

Is it possible, that negating "ccc_uh_mask" here is wrong? How I understand it, "ccc_uh_mask" tells to suppress signals, so it should be positive logic in regard to "da_suppress".

Regards,
Stephan

VCS_I3C_GETPID

Autonomous mode parity write errors

In my configuration I have the register at address "0" configured to be a two byte register. I've set an I3C dynamic address. When writing the register address with bad parity all writes to the registers are ignored as expected. If I use good parity for the register address and bad parity for the first data byte (Least Sig Byte) the write to the first register is accepted (in spite of having bad parity) and the write to the second byte is ignored. If the address byte and first data byte have good parity and the last byte has bad parity then all register bytes are written. Another way to describe the effect is bad parity only has an effect on preceding bytes and not the current byte for writes.

Lint check problem

Lint check on line #154 of file i3c_autonomous.v has a size mismatch.
As is:
assign is_valid[i] = is_writable | is_readable;
I believe this should be:
assign is_valid[i] = is_writable[i] | is_readable[i];

There are other lint size mismatchs mostly related to assignments of "0".

MAP_DA_AUTO[12:8] = 0 causes compile error

When we set MAP_DA_AUTO[12:8] to 0 as specified on page 15 in the uArch spec when PID is not replaced, it causes these errors because PID is set to MAP_DA_AUTO[12:8]:

############### FATAL MESSAGES ############### 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ID       Rule          Alias         Severity    File                                                                                                                          Line    Wt      Message
======================================================================================
[336]    STX_VE_800    STX_VE_800    Syntax      /i3c_regs.v             171     1000    Array bound exceeds integer range in expression [((MAP_CNT * PID_CNT) - 1):0] 
[337]    STX_VE_800    STX_VE_800    Syntax      /i3c_daa_slave.v        159     1000    Array bound exceeds integer range in expression [((MAP_CNT * PID_CNT) - 1):0] 
[338]    STX_VE_800    STX_VE_800    Syntax      /i3c_slave_wrapper.v    256     1000    Array bound exceeds integer range in expression [((MAP_CNT * PID_CNT) - 1):0] 
[339]    STX_VE_800    STX_VE_800    Syntax      /i3c_full_wrapper.v     193     1000    Array bound exceeds integer range in expression [((MAP_CNT * PID_CNT) - 1):0] 

We have made a (temporary) fix by using these settings:

ENA_MAPPED = 5'd1; // Originally 0
MAP_CNT = 4'd1; // Originally 0
MAP_DA_AUTO = 13'h104; // Originally 0

Are we missing something or do you see a better solution?

Latches inferred on dma_r[5:4]

Line 703 to 718 in i3c_regs.v infer latches on dma_r[5:4].

(We use SEL_BUS_IF = 5'b01111 and USE_D_RESET is not defined)

It looks like a tool issue since the latches are gone when adding

	  else
	    dma_r[5:4] <= dma_r[5:4];

after line 711.

See Spyglass and Design Compiler reports below.

Spyglass (SpyGlass_vN-2017.12-SP2) report:

############### Non-BuiltIn -> Goal=lint/lint_rtl ###############
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ID       Rule                 Alias                 Severity    File         Line    Wt    Message
======================================================================================
[1B4]    InferLatch           (OpenMORE 5.5.2.1)    Error       /i3c_regs.v  705     5     Latch inferred for signal '\dma_reg.dma_r [5:4]' in module 'i3c_regs'

Synopsys Design Compiler (2018.06-SP3) report:

Inferred memory devices in process
        in routine i3c_regs_1_000000000000_000_00000000_00_2_55_00_2_000000_1f00_0_0_6_2f_0_10_0000000_8_8_0_0_0_0f_d_0_2_2_0_02_0000_0 line 703 in file
                'i3c_regs.v'.
===============================================================================
|    Register Name    |   Type    | Width | Bus | MB | AR | AS | SR | SS | ST |
===============================================================================
|  dma_reg.dma_r_reg  |   Latch   |   1   |  N  | N  | Y  | N  | -  | -  | -  |
|  dma_reg.dma_r_reg  |   Latch   |   1   |  N  | N  | N  | Y  | -  | -  | -  |
|  dma_reg.dma_r_reg  | Flip-flop |   4   |  Y  | N  | Y  | N  | N  | N  | N  |
===============================================================================

rtl file autonomous reg

define the fbus_index

reg [IDXMX:0]fbus_index;

....

always @(posedge clk_SCL or negedge RSTn)
  if(!RSTn)
     fbus <= 9'd0;


It's a problem.

i2c_spike_ok error

When I do fpga verification,
First,I use I2c to communication,It's works well.
Second,I enter i3c mode,it's fine.
Third, I send RSTDAA CCC command,then,I use I2c communication . It's fail.
Because I2c_spike_ok signal is error.Thanks.

S3 error during DAA results in dyn-address assignment

A error in transmission of address bits or parity bit from I3C master to an I3C slave during DAA phase is detected by the NXP I3C Slave. However, even after detection, the dyn_addr is updated to the new/corrupted data byte and the net dyn_addr_chg is pulsed.

I couldn't find a description on how to handle the address assignment in NXP MIPI I3C spec. Intuitively, the I3C slave should 1) drop the assigned address, 2) NACK that particular write, and 3) wait for exit pattern. Items 2 and 3 are described in the I3C spec but not 1.

Is support for "read current address" missing?

I am trying to implement an EEPROM I2C read/write protocol including "read current address".
Shouldn't it be possible using this I3C slave?

I'm facing two issues related to Read commands.

  1. How to identify early enough that a Read is requested so that the system can provide the data in due time, and even drive the ACK bit (which immediately follows the RnW bit).

  2. How to know when to stop fetching data in the System. When the end/length of the Read command is controlled by the master sending a NACK (and following Stop) the slave has to decide based on the ACK/NACK whether to transmit data on the following SCL clock. But according to simulations (see attached waveforms), the System has to write data (to WDATAB) so that they are available on the same rising edge of SCL which is also used to sample the value of the ACK/NACK bit. So I see no way to support "endless" Read commands without having to pre-fetch the data in the System, and thus performing reads in the System without knowing if they are requested, which can be fatal if the reads have side effects (reading/popping from a FIFO is an example).

The Read command on the I2C protocol I'm talking about can be described as follows (with an undefined number of 'dddddddda' (read data and master ACK) sequences with the Master driving NACK on the last read byte):
SDDDDDDDWaAAAAAAAAaAAAAAAAAaSDDDDDDDRaddddddddaP
S is (re)start,
D is device address bits,
W is the R/W bit driven LOW,
R is the R/W bit drive HIGH,
a is ack driven by the appropriate source (master or slave),
A is the address bits,
d is data bits driven by the appropriate source (master or slave) - slave in the read command here,
P is the stop bit

I'm missing an indication that a read is requested (when the R bit is identified). In the case of a write I can use the dma_req_fb signal or the RXPEND status bit to identify the operation. But it is only the dma_req_tb signal or TXNOTFULL bit that can be used to indicate a read is requested (as far as I can tell - please correct me if i'm wrong).
However, the dma_req_tb signal is asserted by default, so it cannot be used to indicate/trigger a read request (of the first byte).
A solution would be to fill the to-FIFO with data from address A (current address) whenever a Start is identified - using irq.
This will, however, lead to a lot of unwanted pre-fetching of data in the system, since we don't know if it is a read or a write, or even if this device is addressed.
Waiting for a match (using irq - any other way to do it?) will be too late to go fetch data.

By modifying the IP (routing out internal signals - no modification of the behavior of the IP) there is a solution to the first issue (when to begin the Read operation, i.e. fetch data in the System):
The was_read signal inside i3c_sdr_slave_engine.v could be used for indicating a read is requested, but it needs to be qualified by a match signal in order not to issue a System read when reads to other devices are requested.

But I don't see any way to prevent having to pre-fetch data since data has to be ready on the rising edge of SCL when the (N)ACK bit from the Master is sampled.
The first waveform shows data being written to WDATAB too late, thus tb_data_valid is de-asserted.
AckReadTimingFail
The second waveform shows data being written just in time (one PCLK cycle earlier than in the failing example above), thus tb_data_valid stays asserted. As can be seen from the waveform, data has to be written before the rising edge of SCL which samples the (N)ACK bit and consequently the (N)ACK bit cannot be used to trigger the fetching of data in the System.
AckReadTimingPass

Am I missing something?

Thanks

Unsupported syntax in Verilog 2005

The code contains 'standalone' generate blocks (no conditions) which are only allowed in Verilog 2001 but not in Verilog 2005.

These blocks are located here:
i3c_sdr_slave_engine.v: line 780
i3c_daa_slave.v: line 314
i3c_ccc_slave.v: line 539 and 599

All are related to the free version cut.
The issues were found when trying to synthesize the design using Synopsys DC compiler.

BR
/Anders

MS Word errors in i3c_peripheral_slave_uarch.pdf

The architecture document has several broken links, which display as text "Error! Reference source not found.". An example of this can be found on page 3 of the PDF file. It appears that these are Microsoft Word references to figures in the document.

ORUN issue

Hi,
I am observing tb_orun during read . The description says The internal from-bus buffer/FIFO was overrun (too many chars coming in and not drained by the app fast enough).
How to resolve this.

Thanks
Prathusha

Request to have source uploaded as separate files instead of a zip file

Hi,

First of all thanks for sharing this design with the community, as time goes by more and more people embrace the open hardware!

Would it be possible to have the code uploaded as separate files instead of having one zip file?

This distribution approach makes diffing new changes more complicated and I think it goes against the whole point of having a version control system.

Thanks,
Ignacio

About REG_RULES[1] bit

i3c_autonomous_slave.pdf 9 page write

REG_RULES[1]=1 if Write is ignored as soon as run hits
RUN[index]=0 (to protect against over write)

but in file i3c_autonomous_reg.v line No 347

  else if (~REG_RULES[1] & fbus_wr & is_end[next_index] & ~index_magic)
    wr_none <= 1'b1;                // end of run

Dos When REG_RULES[1]=0 ignore RUN[index]=0?

I3c slave configured as i2c slave

Hi,
I m configuring this nxp slave as i2c slave with i2c master, Read operation is not happening, I am able to see the data in fb_data, but read is not being initiated. Can you let me know the configuration required to be set for making it work as i2c.

Thanks
Prats

GETPID CCC not executed

wire da_suppress = vgpio_ccc | (in_ccc[0] & ~ccc_uh_mask); // these collapse if not used

Hi Paul,

please check this line again. I doubt that ccc_uh_mask is correct when compared to the meaning of cccmask register. Could it be, that this should be ccc_uh_r instead?

I continue to see problems when sending GETPID to the target device. The IP decides not to execute GETPID if CCCMASK is a register and bit 0 is set. I expect it to execute it nonetheless, since CCCMASK only should affect CCCs which are not executed directly by the IP (which is NOT the case here).

Please see also my former issue on this: #30

It seems, that GETPID works sporadically depending on the data which is sent after 0x8D (in my case the target address). So maybe this tricked me in believing, that the problem was solved. Try it with address 0x2B, it won't work.

Best regards,
Stephan

Wrong parameter default MAP_DA_AUTO

parameter MAP_DA_AUTO = {5'd0,1'b0,1'b0,3'd0,1'b0,1'b0,1'b0},

Like mentioned in the "Integration Guide", bits 12:8 of MAP_DA_AUTO should be set to '1' if Auto Map DAA is not used. Wouldn't it be more consistent if those bits were set to '1' by default since DAA enable bit 2 is '0' by default? I got compilation errors by using the current defaults.
This affects apb, full and slave wrapper.

file missing for fifo support

Hi,

Could you give me some help with the following questions?

1). From the description, we should be able to adjust the FIFO depth. But after I changed the following parameter, I got "Module 'i3c_internal_fb_fifo' and 'i3c_internal_tb_fifo' not defined.". Did I missed some setting during download and where should I get these missing model?
parameter FIFO_TYPE = 4'b11_01, // From default 4'b10_00
parameter ENA_TOBUS_FIFO = 2, // From default 0
parameter ENA_FROMBUS_FIFO=2, // From default 0

2). I got "Module 'i3c_time_control' is not defined." if set "parameter ENA_IBI_MR_HJ = 1, " Is this function not supported in this version or I missed something?

3). I would like to confirm that the ENA_SADDR can only use one selected method.

4). For the 31 parameters defined in the i3c_apb_wrapper, could you help to list which ones maybe updated by user? Or we have to stick with the default value?

Thanks,

June

Are unhandled CCCs passed through to the mr_* bus?

I do not see a way to configure this I3C so that it passes any unimplemented CCCs through to the magic bus. Am I missing something? I would like to implement a global CCC in the vendor reserved space.

Master ACK not detected during adr arbitration

Hi Paul,

I've been testing IBI requests with your I3C slave IP and a simulation master I wrote from scratch. It seems, I can't get the slave to respond with the mandatory IBI byte after it wrote its address on SDA during address arbitration.

In the screenshot below you can see the master interface + some status signals. Between cursors 1 and 2 (the white ones) the slave address "b4" is written with open drain. After cursor 2 R/W bit '1' follows, which yields the byte "b5". Everything's ok until here.
Now the Slave engine goes from state b (=ADR Arbitration) to state 6 (=MACK) and awaits Master ACK.

The code from sdr_slave_engine is the following at line 547:

    ST_MACK:                            // if IBI or MR or HotJoin, this is Master ACK/NACKing us
      next_state = SDA_r ? ST_WAIT_SrP :// not accepted IBI/MR/HJ 
                   (pend_IBI & ibi_has_byte) ? ST_IBI_BYTE : // IBI byte follows
                   ST_WAIT_SrP;         // done our job, in Master's hands now

Master assigns ACK at the magenta cursor, when the engine already jumps to wait state ST_WAIT_SrP=0, since registered SDA_r (which shows clock/2 after SDA) is still '1'. So it seems to me, that I don't have a chance to reach state ST_IBI_BYTE (pend_IBI and ibi_has_byte are true, although not shown in the graph), since SDA is always evaluated half a clock too early and is held '1' the clock before by the slaves R/W bit.
Do you agree or am I doing something wrong here? I'm grateful for every hint -

Regards,
Stephan

VCS_I3C_IBI

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.