{"id":644,"date":"2021-04-04T23:20:47","date_gmt":"2021-04-04T16:20:47","guid":{"rendered":"https:\/\/bigdolphin.com.vn\/?p=644"},"modified":"2024-03-26T15:26:56","modified_gmt":"2024-03-26T08:26:56","slug":"ip-core-for-interfacing-between-wireless-ps2-playstation-and-de10-nano","status":"publish","type":"post","link":"https:\/\/bigdolphin.com.vn\/?p=644","title":{"rendered":"IP Core for interfacing between PS2 Controller and DE10-nano"},"content":{"rendered":"\n<h3 class=\"wp-block-heading\"><strong>1. Pinout of PS2 Controller<\/strong><\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/bigdolphin.com.vn\/wp-content\/uploads\/2021\/04\/P2_Pin.png\" alt=\"\" class=\"wp-image-636\" width=\"482\" height=\"441\" srcset=\"https:\/\/bigdolphin.com.vn\/wp-content\/uploads\/2021\/04\/P2_Pin.png 963w, https:\/\/bigdolphin.com.vn\/wp-content\/uploads\/2021\/04\/P2_Pin-300x274.png 300w, https:\/\/bigdolphin.com.vn\/wp-content\/uploads\/2021\/04\/P2_Pin-768x703.png 768w\" sizes=\"(max-width: 482px) 100vw, 482px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>2. Connection to DE10 nano<\/strong><\/h3>\n\n\n\n<ul>\n  <li>DATA -&gt; GPIO_1[4]<\/li>\n  <li>ATTENTION (CS) -&gt; GPIO_1[3]<\/li>\n  <li>CLOCK -&gt; GPIO_1[1]<\/li>\n  <li>COMMAND -&gt; GPIO_1[5]<\/li>\n<\/ul>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-layout-1 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/bigdolphin.com.vn\/wp-content\/uploads\/2021\/04\/DE10-nano.png\" alt=\"\" class=\"wp-image-629\" width=\"299\" height=\"294\" srcset=\"https:\/\/bigdolphin.com.vn\/wp-content\/uploads\/2021\/04\/DE10-nano.png 388w, https:\/\/bigdolphin.com.vn\/wp-content\/uploads\/2021\/04\/DE10-nano-300x295.png 300w\" sizes=\"(max-width: 299px) 100vw, 299px\" \/><\/figure><\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/bigdolphin.com.vn\/wp-content\/uploads\/2021\/04\/DE10-GPIO.png\" alt=\"\" class=\"wp-image-630\" width=\"562\" height=\"317\" srcset=\"https:\/\/bigdolphin.com.vn\/wp-content\/uploads\/2021\/04\/DE10-GPIO.png 922w, https:\/\/bigdolphin.com.vn\/wp-content\/uploads\/2021\/04\/DE10-GPIO-300x170.png 300w, https:\/\/bigdolphin.com.vn\/wp-content\/uploads\/2021\/04\/DE10-GPIO-768x434.png 768w\" sizes=\"(max-width: 562px) 100vw, 562px\" \/><\/figure><\/div>\n<\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>3.&nbsp;System Verilog<\/strong><\/h3>\n\n\n\n<p><strong>a.&nbsp;IP core<\/strong><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/bigdolphin.com.vn\/wp-content\/uploads\/2021\/04\/PS2_coreIP.png\" alt=\"\" class=\"wp-image-631\" width=\"459\" height=\"311\" srcset=\"https:\/\/bigdolphin.com.vn\/wp-content\/uploads\/2021\/04\/PS2_coreIP.png 612w, https:\/\/bigdolphin.com.vn\/wp-content\/uploads\/2021\/04\/PS2_coreIP-300x203.png 300w\" sizes=\"(max-width: 459px) 100vw, 459px\" \/><\/figure><\/div>\n\n\n\n<p><strong>b.&nbsp;Internal registers<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"c\" class=\"language-c line-numbers\"><strong>parameter<\/strong> counterBitMax = <strong>96<\/strong>;\n<strong>reg<\/strong>    [<strong>counterBitMax:0<\/strong>]       status;\n<strong>reg<\/strong>                            signal_clk;\n<strong>reg<\/strong>                            signal_cmd;\n<strong>reg<\/strong>                            signal_data;\n<strong>reg<\/strong>                            signal_att;\n<strong>reg<\/strong>    [            <strong>6<\/strong>:<strong>0<\/strong>]       counterCLK;\n<strong>reg<\/strong>    [           <strong>17<\/strong>:<strong>0<\/strong>]       counterATT;\n<strong>reg<\/strong>    [<strong>counterBitMax:0<\/strong>]       Data_cmd;\n<strong>reg<\/strong>    [            <strong>7<\/strong>:<strong>0<\/strong>]       counterBit;<\/code><\/pre>\n\n\n\n<p><strong>c.&nbsp;Logic control and clock generator<\/strong><\/p>\n\n\n\n<ul><li>Activating Attention every 50ms.<\/li><li>In each period of 50ms,&nbsp;generate clock to read 96 bit.<\/li><li>Deactivating Attention after transferring 96 bit data completely.<\/li><li>The IP core uses 3.072 MHz clock.<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"c\" class=\"language-c line-numbers\">\/\/ Generating SCLK generation and Controlling ATT\nalways_ff @ (posedge clk_3072) begin\n\u00a0\u00a0\u00a0\u00a0if (reset) begin\n \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0counterATT &lt;= 0;\n  \u00a0\u00a0\u00a0 \u00a0\u00a0signal_att &lt;= 1'b1;\n  \u00a0\u00a0\u00a0 \u00a0\u00a0counterCLK &lt;= 0;\n  \u00a0\u00a0\u00a0 \u00a0\u00a0signal_clk &lt;= 1'b1;\n  \u00a0\u00a0\u00a0 \u00a0\u00a0counterBit &lt;= 0;\n\u00a0\u00a0\u00a0\u00a0end\n\u00a0\u00a0\u00a0\u00a0else begin\n  \u00a0\u00a0\u00a0 \u00a0\u00a0if (counterATT > 153600) begin\n  \u00a0\u00a0\u00a0 \u00a0\u00a0    counterATT &lt;= 0;\n  \u00a0\u00a0\u00a0 \u00a0\u00a0    signal_att &lt;= 0;\n  \u00a0\u00a0\u00a0 \u00a0\u00a0    counterCLK &lt;= 0;\n  \u00a0\u00a0\u00a0 \u00a0\u00a0    signal_clk &lt;= 1'b1;\n  \u00a0\u00a0\u00a0 \u00a0\u00a0    counterBit &lt;= 0;\n  \u00a0\u00a0\u00a0 \u00a0\u00a0end\n  \u00a0\u00a0\u00a0 \u00a0\u00a0else begin\n  \u00a0\u00a0\u00a0 \u00a0\u00a0    if (counterBit > counterBitMax) begin\n  \u00a0\u00a0\u00a0 \u00a0\u00a0        signal_att &lt;= 1'b1;\n  \u00a0\u00a0\u00a0 \u00a0\u00a0        counterCLK &lt;= 0;\n  \u00a0\u00a0\u00a0 \u00a0\u00a0        signal_clk &lt;= 1'b1; \u00a0\n  \u00a0\u00a0\u00a0 \u00a0\u00a0    end\n  \u00a0\u00a0\u00a0 \u00a0\u00a0    else begin\n  \u00a0\u00a0\u00a0 \u00a0\u00a0        signal_att &lt;= 0; \u00a0\n  \u00a0\u00a0\u00a0 \u00a0\u00a0        if (counterCLK > 77) begin\n  \u00a0\u00a0\u00a0 \u00a0\u00a0            counterCLK &lt;= 0;\n  \u00a0\u00a0\u00a0 \u00a0\u00a0            signal_clk &lt;= ~signal_clk;\n  \u00a0\u00a0\u00a0 \u00a0\u00a0            if (signal_clk) begin\n  \u00a0\u00a0\u00a0 \u00a0\u00a0                counterBit &lt;= counterBit + 1'b1;\n  \u00a0\u00a0\u00a0 \u00a0\u00a0            end\n  \u00a0\u00a0\u00a0 \u00a0\u00a0        end\n  \u00a0\u00a0\u00a0 \u00a0\u00a0        else begin\n  \u00a0\u00a0\u00a0 \u00a0\u00a0            counterCLK &lt;= counterCLK + 1'b1;\n  \u00a0\u00a0\u00a0 \u00a0\u00a0        end \u00a0\n  \u00a0\u00a0\u00a0 \u00a0\u00a0    end \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\n  \u00a0\u00a0\u00a0 \u00a0\u00a0    counterATT &lt;= counterATT + 1'b1;\n  \u00a0\u00a0\u00a0 \u00a0\u00a0end \u00a0\u00a0\n\u00a0\u00a0\u00a0\u00a0end\nend<\/code><\/pre>\n\n\n\n<p><strong>d.&nbsp;Write to controller<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"c\" class=\"language-c line-numbers\">\/\/ Write to Controller\n<strong>always_ff<\/strong>\u00a0@ (<strong>negedge<\/strong>\u00a0signal_clk) <strong>begin<\/strong>\n\u00a0\u00a0\u00a0\u00a0<strong>if<\/strong>\u00a0(reset) <strong>begin<\/strong>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0signal_cmd &lt;=\u00a0<strong>'x<\/strong>;\n\u00a0\u00a0\u00a0\u00a0<strong>end<\/strong>\n\u00a0\u00a0\u00a0\u00a0<strong>else<\/strong>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0signal_cmd &lt;=\u00a0Data_cmd[counterBit];\n<strong>end<\/strong><\/code><\/pre>\n\n\n\n<p><strong>e.&nbsp;Read from controller<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"c\" class=\"language-c line-numbers\">\/\/ Read from Controller\n<strong>always_ff<\/strong>\u00a0@ (<strong>negedge<\/strong>\u00a0signal_clk) <strong>begin<\/strong>\n\u00a0\u00a0\u00a0\u00a0<strong>if<\/strong>\u00a0(reset) <strong>begin<\/strong>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0status &lt;=\u00a0<strong>0<\/strong>;\n\u00a0\u00a0\u00a0\u00a0<strong>end<\/strong>\n\u00a0\u00a0\u00a0\u00a0<strong>else<\/strong>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0status[counterBit] &lt;=\u00a0signal_data;\n<strong>end<\/strong><\/code><\/pre>\n\n\n\n<p><strong>f.&nbsp;Send data to Avalon<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"c\" class=\"language-c line-numbers\">\/\/ Read operations performed on the Avalon-MM Slave interface\n<strong>always_ff<\/strong>\u00a0@ (<strong>posedge<\/strong>\u00a0clk) <strong>begin<\/strong>\n\u00a0\u00a0\u00a0\u00a0<strong>if<\/strong>\u00a0(reset) <strong>begin<\/strong>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0avs_s0_readdata &lt;=\u00a0<strong>'x<\/strong>;  \u00a0\n\u00a0\u00a0\u00a0\u00a0<strong>end<\/strong>\n\u00a0\u00a0\u00a0\u00a0<strong>else<\/strong>\u00a0<strong>if<\/strong>\u00a0(avs_s0_read) <strong>begin<\/strong>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<strong>case<\/strong>\u00a0(avs_s0_address)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<strong>2'd0<\/strong>\u00a0\u00a0\u00a0\u00a0:\u00a0avs_s0_readdata &lt;=\u00a0status[<strong>31<\/strong>:<strong>0<\/strong>];\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<strong>2'd1<\/strong>\u00a0\u00a0\u00a0\u00a0:\u00a0avs_s0_readdata &lt;=\u00a0status[<strong>63<\/strong>:<strong>32<\/strong>];\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<strong>2'd2<\/strong>\u00a0\u00a0\u00a0\u00a0:\u00a0avs_s0_readdata &lt;=\u00a0status[<strong>95<\/strong>:<strong>64<\/strong>];\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<strong>default<\/strong>\u00a0:\u00a0avs_s0_readdata &lt;=\u00a0<strong>'x<\/strong>;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<strong>endcase<\/strong> \n\u00a0\u00a0\u00a0\u00a0<strong>end<\/strong>\n\u00a0\u00a0\u00a0\u00a0<strong>else<\/strong>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0avs_s0_readdata &lt;=\u00a0<strong>'x<\/strong>;\n<strong>end<\/strong><\/code><\/pre>\n\n\n\n<p><strong>g.&nbsp;Build command from data which is sent from Avalon<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"c\" class=\"language-c line-numbers\">\/\/ Write operations performed on the Avalon-MM Slave interface\n<strong>always_ff<\/strong>\u00a0@ (<strong>posedge<\/strong>\u00a0clk) <strong>begin<\/strong>\n\u00a0\u00a0\u00a0\u00a0<strong>if<\/strong>\u00a0(reset) <strong>begin<\/strong>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Data_cmd &lt;=\u00a0{{<strong>80<\/strong>{<strong>1'b0<\/strong>}},<strong>8'h42<\/strong>,<strong>8'h01<\/strong>};\n\u00a0\u00a0\u00a0\u00a0<strong>end<\/strong>\n\u00a0\u00a0\u00a0\u00a0<strong>else<\/strong>\u00a0<strong>begin<\/strong>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<strong>if<\/strong>\u00a0(avs_s0_write) <strong>begin<\/strong>  \u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<strong>case<\/strong>\u00a0(avs_s0_address)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<strong>2'd0<\/strong>\u00a0\u00a0\u00a0\u00a0:\u00a0Data_cmd[<strong>31<\/strong>:<strong>0<\/strong>] &lt;=\u00a0avs_s0_writedata;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<strong>2'd1<\/strong>\u00a0\u00a0\u00a0\u00a0:\u00a0Data_cmd[<strong>63<\/strong>:<strong>32<\/strong>] &lt;=\u00a0avs_s0_writedata;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<strong>2'd2<\/strong>\u00a0\u00a0\u00a0\u00a0:\u00a0Data_cmd[<strong>95<\/strong>:<strong>64<\/strong>] &lt;=\u00a0avs_s0_writedata;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<strong>default<\/strong>\u00a0:\u00a0Data_cmd &lt;=\u00a0{{<strong>80<\/strong>{<strong>1'b0<\/strong>}},<strong>8'h42<\/strong>,<strong>8'h01<\/strong>};\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<strong>endcase<\/strong>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<strong>end<\/strong>\n\u00a0\u00a0\u00a0\u00a0<strong>end<\/strong>\n<strong>end<\/strong><\/code><\/pre>\n\n\n\n<p><strong>h.&nbsp;Assign logic states<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"c\" class=\"language-c line-numbers\"><strong>assign<\/strong>\u00a0ps_cs \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0=\u00a0signal_att;\n<strong>assign<\/strong>\u00a0ps_clk \u00a0\u00a0\u00a0\u00a0\u00a0=\u00a0signal_clk;\n<strong>assign<\/strong>\u00a0ps_cmd \u00a0\u00a0\u00a0\u00a0\u00a0=\u00a0signal_cmd;\n<strong>assign<\/strong>\u00a0signal_data =\u00a0ps_dat;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">4.&nbsp;C\/C++&nbsp;code to communicate with the IP core<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp line-numbers\">\/* Playstation wireless *\/\nprintf(\"<strong>\\r\\n<\/strong>---> Playstation IP...<strong>\\r\\n<\/strong>\");\nplaystation_ip_map =\u00a0getBASE(virtual_base,ALT_LWFPGASLVS_OFST,PLAYSTATION_WIRELESS_0_BASE,HW_REGS_MASK);\ni =\u00a0<strong>0<\/strong>;\n<strong>while<\/strong>(<strong>1<\/strong>){ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\n\u00a0\u00a0\u00a0\u00a0printf(\"[%d] playstation_ip_map @ LW = 0x%08X,%08X,%08X @ %X<strong>\\r\\n<\/strong>\",i,*(playstation_ip_map +\u00a0<strong>0x02<\/strong>),*(playstation_ip_map +\u00a0<strong>0x01<\/strong>),*playstation_ip_map,(<strong>uint32_t<\/strong>)playstation_ip_map);\n\u00a0\u00a0\u00a0\u00a0i++;\n\u00a0\u00a0\u00a0\u00a0\/\/ Wait 0.2s\n\u00a0\u00a0\u00a0\u00a0usleep(<strong>200000<\/strong>);\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">5.&nbsp;Testing<\/h3>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"Andromeda PS2\" width=\"500\" height=\"281\" src=\"https:\/\/www.youtube.com\/embed\/wOLsXLpW--Q?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>A system verilog IP core to control Andromeda robot from PS2 Controller.<\/p>\n","protected":false},"author":2,"featured_media":638,"comment_status":"open","ping_status":"open","sticky":false,"template":"single-with-sidebar","format":"standard","meta":{"gtb_hide_title":false,"gtb_wrap_title":false,"gtb_class_title":"","gtb_remove_headerfooter":false,"footnotes":""},"categories":[10],"tags":[4,6,7,8,5],"_links":{"self":[{"href":"https:\/\/bigdolphin.com.vn\/index.php?rest_route=\/wp\/v2\/posts\/644"}],"collection":[{"href":"https:\/\/bigdolphin.com.vn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bigdolphin.com.vn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bigdolphin.com.vn\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/bigdolphin.com.vn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=644"}],"version-history":[{"count":12,"href":"https:\/\/bigdolphin.com.vn\/index.php?rest_route=\/wp\/v2\/posts\/644\/revisions"}],"predecessor-version":[{"id":862,"href":"https:\/\/bigdolphin.com.vn\/index.php?rest_route=\/wp\/v2\/posts\/644\/revisions\/862"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/bigdolphin.com.vn\/index.php?rest_route=\/wp\/v2\/media\/638"}],"wp:attachment":[{"href":"https:\/\/bigdolphin.com.vn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=644"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bigdolphin.com.vn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=644"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bigdolphin.com.vn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=644"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}