{"id":696,"date":"2015-05-15T16:49:00","date_gmt":"2015-05-16T00:49:00","guid":{"rendered":"http:\/\/www.beyond-circuits.com\/wordpress\/?page_id=696"},"modified":"2023-11-12T14:47:33","modified_gmt":"2023-11-12T22:47:33","slug":"part4","status":"publish","type":"page","link":"https:\/\/www.beyond-circuits.com\/wordpress\/tutorial\/tutorial18\/part4\/","title":{"rendered":"Tutorial 18: I2S Receiver, part 4"},"content":{"rendered":"<h1>AXI4 Streaming<\/h1>\n<p>In this final part of tutorial 18, we&#8217;re going to add an AXI4 streaming interface to the I2S receiver. This interface will allow the receiver to play with the Vivado IP tool flow.<\/p>\n<h2>AXI4 Streaming Overview<\/h2>\n<p>The ARM AXI4 standard has two types of interfaces. First, there&#8217;s the memory mapped AXI4 and AXI4-Lite interfaces, of which we have seen the AXI4-Lite before. These interfaces implement a microprocessor bus interface. Transactions are reads and writes of data to memory addresses.<\/p>\n<p>Streaming interfaces like the AXI4 Streaming interface are different. They don&#8217;t have a concept of addresses, and data transfers can only occur in one direction. They&#8217;re meant to handle a stream of information\u2013 sort of like a network packet, or audio data like that produced by our I2S receiver. A streaming interface can either be a master or a slave. Master interfaces generate data that are sent to slaves. So, our I2S receiver is a I2S slave interface\u2013 it receives data from an I2S master, so therefore it is an AXI4 Streaming master interface. In tutorial 19 we will design a I2S transmitter interface which is an I2S master and will have an AXI4 slave interface. We will be able to extend our audio loopback design once we have these two IP blocks.<\/p>\n<h2>Signals<\/h2>\n<p>An AXI4 Streaming interface uses the signals shown in the following table:<\/p>\n<div class=\"table-responsive\"><table  style=\"width:100%; \"  class=\"easy-table easy-table-default \" border=\"0\">\n<thead>\r\n<tr><th >Signal<\/th>\n<th > Source<\/th>\n<th > Description<\/th>\n<\/tr>\n<\/thead>\n<tbody>\r\n<tr><td >ACLK<\/td>\n<td > Clock source<\/td>\n<td > The clock signal for the interface used by both the slave and master. All signals are sampled and generated from the rising edge of this clock.<\/td>\n<\/tr>\n\r\n<tr><td >ARESETn<\/td>\n<td > Reset source<\/td>\n<td > Active low reset for the interface.<\/td>\n<\/tr>\n\r\n<tr><td >TVALID<\/td>\n<td > Master<\/td>\n<td > Indicates that the master is driving a valid transfer.<\/td>\n<\/tr>\n\r\n<tr><td >TREADY<\/td>\n<td > Slave<\/td>\n<td > Indicates the slave is ready to receive the transfer.<\/td>\n<\/tr>\n\r\n<tr><td >TDATA<\/td>\n<td > Master<\/td>\n<td > The data being transferred.<\/td>\n<\/tr>\n\r\n<tr><td >TLAST<\/td>\n<td > Master<\/td>\n<td > Indicates that this transfer is the last transfer in the packet.<\/td>\n<\/tr>\n\r\n<tr><td >TSTRB<\/td>\n<td > Master (optional)<\/td>\n<td > One bit in this bus for each byte in TDATA indicates whether the data byte is valid.<\/td>\n<\/tr>\n\r\n<tr><td >TKEEP<\/td>\n<td > Master (optional)<\/td>\n<td > Indicates bits which should be kept as part of the data stream.<\/td>\n<\/tr>\n\r\n<tr><td >TID<\/td>\n<td > Master (optional)<\/td>\n<td > The data stream identifier.<\/td>\n<\/tr>\n\r\n<tr><td >TDEST<\/td>\n<td > Master (optional)<\/td>\n<td > Routing information for the data stream.<\/td>\n<\/tr>\n\r\n<tr><td >TUSER<\/td>\n<td > Master (optional)<\/td>\n<td > User defined sideband information.<\/td>\n<\/tr>\n<\/tbody><\/table><\/div>\n<h2>Handshake<\/h2>\n<p>Information flows from the master to the slave. They both receive the bus clock and reset signals from other sources. The slave generates only a <em>TREADY<\/em> signal to indicate that it is ready to receive data, and the master generates all other signals. A transfer occurs whenever TREADY and TVALID are both high on the rising edge of <em>ACLK<\/em>.<\/p>\n<p>A master is not permitted to wait for <em>TREADY<\/em> to be asserted before asserting <em>TVALID<\/em>. However, a slave is permitted to wait for <em>TVALID<\/em> to be asserted before asserting <em>TREADY<\/em>. In addition, a slave may assert and de-assert <em>TREADY<\/em> without receiving an intermediate <em>TVALID<\/em>.<\/p>\n<div id=\"attachment_781\" style=\"width: 310px\" class=\"wp-caption alignright\"><a href=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/04\/tutorial18_axi4_timing1.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-781\" class=\"size-medium wp-image-781\" src=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/04\/tutorial18_axi4_timing1-300x149.png\" alt=\"TVALID before TREADY handshake\" width=\"300\" height=\"149\" srcset=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/04\/tutorial18_axi4_timing1-300x149.png 300w, https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/04\/tutorial18_axi4_timing1-500x249.png 500w, https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/04\/tutorial18_axi4_timing1.png 560w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-781\" class=\"wp-caption-text\">TVALID before TREADY handshake<\/p><\/div>\n<p>In the timing diagram to the right, the master presents the transfer information and <em>TVALID<\/em>. <em>TVALID<\/em> must remain active until the slave drive&#8217;s <em>TREADY<\/em>. The transfer occurs when both <em>TVALID<\/em> and <em>TREADY<\/em> are asserted at the rising edge of <em>ACLK<\/em>. This is shown with the arrow in the timing diagram.<\/p>\n<div id=\"attachment_782\" style=\"width: 310px\" class=\"wp-caption alignright\"><a href=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/04\/tutorial18_axi4_timing2.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-782\" class=\"size-medium wp-image-782\" src=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/04\/tutorial18_axi4_timing2-300x149.png\" alt=\"TREADY before TVALID handshake\" width=\"300\" height=\"149\" srcset=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/04\/tutorial18_axi4_timing2-300x149.png 300w, https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/04\/tutorial18_axi4_timing2-500x248.png 500w, https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/04\/tutorial18_axi4_timing2.png 562w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-782\" class=\"wp-caption-text\">TREADY before TVALID handshake<\/p><\/div>\n<p>In the case shown to the right, the slave presents <em>TREADY<\/em> and then subsequently the master asserts <em>TVALID<\/em>. The transfer occurs when both signals are asserted and <em>ACLK<\/em> rises. This is again shown with the arrow.<\/p>\n<div id=\"attachment_783\" style=\"width: 310px\" class=\"wp-caption alignright\"><a href=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/04\/tutorial18_axi4_timing3.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-783\" class=\"size-medium wp-image-783\" src=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/04\/tutorial18_axi4_timing3-300x149.png\" alt=\"TVALID with TREADY handshake\" width=\"300\" height=\"149\" srcset=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/04\/tutorial18_axi4_timing3-300x149.png 300w, https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/04\/tutorial18_axi4_timing3-500x249.png 500w, https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/04\/tutorial18_axi4_timing3.png 560w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-783\" class=\"wp-caption-text\">TVALID with TREADY handshake<\/p><\/div>\n<p>In the timing diagram to the right, the master asserts <em>TVALID<\/em> in the same cycle that the slave asserts <em>TREADY<\/em>. The transfer occurs that cycle as indicated by the arrow.<\/p>\n<h1>Signalling<\/h1>\n<div id=\"attachment_784\" style=\"width: 310px\" class=\"wp-caption alignright\"><a href=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/04\/tutorial18_axi4_timing4.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-784\" class=\"size-medium wp-image-784\" src=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/04\/tutorial18_axi4_timing4-300x182.png\" alt=\"I2S audio packet transfer\" width=\"300\" height=\"182\" srcset=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/04\/tutorial18_axi4_timing4-300x182.png 300w, https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/04\/tutorial18_axi4_timing4-496x300.png 496w, https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/2015\/04\/tutorial18_axi4_timing4.png 560w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-784\" class=\"wp-caption-text\">I2S audio packet transfer<\/p><\/div>\n<p>In our case, we only need to send the 32 bits of audio data on <em>TDATA<\/em> and indicate the end of the packet with <em>TLAST<\/em>. On the first transfer cycle, we&#8217;ll send the left channel data with <em>TLAST<\/em> low, and then on the second transfer we will send the right channel data with <em>TLAST<\/em> high. Our application will not need any of the optional AXI4 Streaming signals.<\/p>\n<h1>Naming<\/h1>\n<p>In Vivado, we&#8217;re going to want to use a naming convention which allows the IP Packager tool to recognize the signals in the AXI4 Streaming interface. To do this, we&#8217;ll prefix all of our port names in the interface with <code>M_AXIS_<\/code>. Here is a list of the signal names we need to use:<\/p>\n<div class=\"table-responsive\"><table  style=\"width:100%; \"  class=\"easy-table easy-table-default \" border=\"0\">\n<thead>\r\n<tr><th >Signal<\/th>\n<th > Direction<\/th>\n<th > Description<\/th>\n<\/tr>\n<\/thead>\n<tbody>\r\n<tr><td >M_AXIS_ACLK<\/td>\n<td > Input<\/td>\n<td > This is the clock signal for the module. It is driven in to both the master and the slave.<\/td>\n<\/tr>\n\r\n<tr><td >M_AXIS_ARESETN<\/td>\n<td > Input<\/td>\n<td > When this signal is low you should reset the M_AXIS_TVALID signal so that you don't indicate you have valid data to drive.<\/td>\n<\/tr>\n\r\n<tr><td >M_AXIS_TVALID<\/td>\n<td > Output<\/td>\n<td > Indicates that you have valid data to transfer to the slave.<\/td>\n<\/tr>\n\r\n<tr><td >M_AXIS_TREADY<\/td>\n<td > Input<\/td>\n<td > Indicates the slave is ready to receive your transfer.<\/td>\n<\/tr>\n\r\n<tr><td >M_AXIS_TDATA<\/td>\n<td > Output<\/td>\n<td > The data being transferred.<\/td>\n<\/tr>\n\r\n<tr><td >M_AXIS_TLAST<\/td>\n<td > Output<\/td>\n<td > Indicates that this transfer is the last transfer in the packet. There are two transfers per packet. The first is the left data and the last is the right data.<\/td>\n<\/tr>\n<\/tbody><\/table><\/div>\n<h1>Logic<\/h1>\n<p>You will need to add logic to generate <em>M_AXIS_TVALID<\/em>. This will need to get set when data is available to transfer to the AXI4 Streaming interface. It will need to clear when the data is read by the AXI4 slave, as indicated by <em>M_AXIS_TREADY<\/em>. Also, you will need to reset this to zero when M_AXIS_ARESETN is low.<\/p>\n<p>You&#8217;re going to need to provide some type of selection logic which drives the left or right channel data onto the <em>M_AXIS_TDATA<\/em> output, depending on which channel we are sending.<\/p>\n<p>Finally, you&#8217;ll also need to make a <em>M_AXIS_TLAST<\/em> output which indicates that the right channel is being read.<\/p>\n<h1>Test<\/h1>\n<p>The test is much like the previous parts for this tutorial, but it also adds a <em>Bus Functional Model<\/em> for the AXI4 slave interface. This model will accept the data transferred by your I2S receiver interface. It\u00a0also uses a Queue model to hold expected data values. Those files along with the test are linked here:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.beyond-circuits.com\/repos\/tutorial\/trunk\/tests\/i2s_receive_test.v\">i2s_receive_test.v<\/a><\/li>\n<li><a href=\"https:\/\/www.beyond-circuits.com\/repos\/tutorial\/trunk\/tbench\/queue.v\">queue.v<\/a><\/li>\n<li><a href=\"https:\/\/www.beyond-circuits.com\/repos\/tutorial\/trunk\/rtl\/common_util.vh\">common_util.vh<\/a><\/li>\n<li><a href=\"https:\/\/www.beyond-circuits.com\/repos\/tutorial\/trunk\/tbench\/common_test_util.v\">common_test_util.v<\/a><\/li>\n<li><a href=\"https:\/\/www.beyond-circuits.com\/wordpress\/wp-content\/uploads\/tutorials\/tutorial18\/axi4_streaming_slave_bfm.v\">axi4_streaming_slave_bfm.v<\/a><\/li>\n<\/ul>\n<p>The test will send I2S transactions to your design and receive AXI4 transactions from it. It will check that the received left and right data match, and that each packet has eight bytes of data. There can be issues in synchronizing your design with the test. If this happens, the test may report a large number of errors, but in fact there is just an alignment issue in that your logic generated extra initial AXI4 packets with uninitialized data. When you get errors, look at the first errors and see what the problem might be. Are the outputs shifted in time from the expected outputs? Are the left and right channels swapped? Are the left and right samples paired with the wrong packet? These could all be\u00a0errors.<\/p>\n<p>The test will not try to read a packet from your design until it has completed sending an I2S sample. It&#8217;s legal for your design to assert that it has valid data, even though it doesn&#8217;t initially. It&#8217;ll still work just as long as by the time the first I2S sample (both left and right) are sent, your logic has\u00a0valid data.<\/p>\n<h1>Hints<\/h1>\n<p>At first blush, this design seems more complicated than it really is. If you find yourself adding lots of logic you are probably going down the wrong path. The simplest thing to do is get rid of the <em>data_left<\/em> and <em>data_right<\/em> registers and just replace them with a <em>M_AXIS_TDATA<\/em> register. This will hold left and right samples alternating in time. Then you just need an always block to create the <em>M_AXIS_TVALID<\/em> output and another to create the <em>M_AXIS_TLAST<\/em> output.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>AXI4 Streaming In this final part of tutorial 18, we&#8217;re going to add an AXI4 streaming interface to the I2S receiver. This interface will allow the receiver to play with the Vivado IP tool flow. AXI4 Streaming Overview The ARM &hellip; <a href=\"https:\/\/www.beyond-circuits.com\/wordpress\/tutorial\/tutorial18\/part4\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"parent":638,"menu_order":4,"comment_status":"open","ping_status":"open","template":"","meta":{"footnotes":""},"class_list":["post-696","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages\/696","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/comments?post=696"}],"version-history":[{"count":16,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages\/696\/revisions"}],"predecessor-version":[{"id":1375,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages\/696\/revisions\/1375"}],"up":[{"embeddable":true,"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/pages\/638"}],"wp:attachment":[{"href":"https:\/\/www.beyond-circuits.com\/wordpress\/wp-json\/wp\/v2\/media?parent=696"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}