{"id":1952,"date":"2022-03-23T21:44:06","date_gmt":"2022-03-23T20:44:06","guid":{"rendered":"http:\/\/www.fabienm.eu\/flf\/?p=1952"},"modified":"2022-03-23T21:44:07","modified_gmt":"2022-03-23T20:44:07","slug":"sv2chisel-le-convertisseur-systemverilog-vers-chisel","status":"publish","type":"post","link":"http:\/\/www.fabienm.eu\/flf\/sv2chisel-le-convertisseur-systemverilog-vers-chisel\/","title":{"rendered":"sv2chisel, le convertisseur (System)Verilog vers Chisel"},"content":{"rendered":"\n<p>Le monde du FPGA (et de l&rsquo;ASIC) regorge aujourd&rsquo;hui de langages de description mat\u00e9riel. Au <a href=\"http:\/\/www.fabienm.eu\/flf\/hdl\/verilog\/\">Verilog<\/a> et <a href=\"http:\/\/www.fabienm.eu\/flf\/hdl\/vhdl\/\">VHDL<\/a> s&rsquo;ajoute maintenant tout un tas de langages comme <a href=\"http:\/\/www.fabienm.eu\/flf\/hdl\/migen\/\">Migen<\/a>, <a href=\"http:\/\/www.fabienm.eu\/flf\/hdl\/c%ce%bbash\/\">Clash<\/a>, <a href=\"http:\/\/www.fabienm.eu\/flf\/hdl\/bluespec\/\">BlueSpec<\/a>, <a href=\"http:\/\/www.fabienm.eu\/flf\/hdl\/amaranth\/\">Amaranth<\/a>, <a href=\"http:\/\/www.fabienm.eu\/flf\/hdl\/chisel\/\">Chisel<\/a>, <a href=\"http:\/\/www.fabienm.eu\/flf\/hdl\/spinalhdl\/\">SpinalHDL<\/a>, <a href=\"http:\/\/www.fabienm.eu\/flf\/hdl\/silice\/\">Silice<\/a>, &#8230; et j&rsquo;en oublie plein. Tous ces langages permettent de g\u00e9n\u00e9rer du Verilog.  Les possibilit\u00e9 de conversion de VHDL vers Verilog ne sont maintenant plus une utopie gr\u00e2ce aux \u00e9volutions de <a href=\"https:\/\/ghdl.github.io\/ghdl\/\">GHDL<\/a> et de <a href=\"https:\/\/yosyshq.net\/yosys\/\">Yosys<\/a>.<\/p>\n\n\n\n<p>Bref, il existe d\u00e9sormais toujours une possibilit\u00e9 de convertir l&rsquo;int\u00e9gralit\u00e9 du projet en Verilog de mani\u00e8re \u00e0 le simuler et synth\u00e9tiser avec les outils con\u00e7us pour lui.<\/p>\n\n\n\n<p>C&rsquo;est quelque chose de tr\u00e8s appr\u00e9ciable pour faire de la r\u00e9utilisation de code. Il n&rsquo;est plus n\u00e9cessaire de re-concevoir un composant en VHDL tout \u00e7a parce que le contr\u00f4leur open source qui nous est n\u00e9cessaire est cod\u00e9 en Verilog.<\/p>\n\n\n\n<p>L\u2019homog\u00e9n\u00e9it\u00e9 de langage des sources d&rsquo;un projet peut cependant \u00eatre appr\u00e9ciable dans certain cas. Notamment quand le langage de description poss\u00e8de ses propres librairies de simulation comme c&rsquo;est le cas en Chisel.<\/p>\n\n\n\n<p>On peut certes instancier les \u00absous\u00bb-modules Verilog au moyen de <a href=\"https:\/\/www.chisel-lang.org\/chisel3\/docs\/explanations\/blackboxes.html\">BlackBox<\/a>, mais ils ne seront pas simulable avec <a href=\"https:\/\/www.chisel-lang.org\/chiseltest\/\">ChiselTest<\/a> par exemple car <a href=\"https:\/\/www.chisel-lang.org\/treadle\/\">treadle<\/a> se cassera les dents dessus.   <\/p>\n\n\n\n<p>C&rsquo;est l\u00e0 qu&rsquo;intervient le nouveau projet nomm\u00e9 <a href=\"https:\/\/github.com\/ovh\/sv2chisel\">sv2chisel<\/a> pour convertir du (system)Verilog en chisel.<\/p>\n\n\n\n<p>Je vous propose ici de tester ensemble l&rsquo;utilitaire dans un cas pratique. Je souhaite convertir le module Verilog <a href=\"https:\/\/github.com\/lawrie\/ulx3s_examples\/blob\/master\/hdmi\/fake_differential.v\">fake_differential <\/a>du projet d&rsquo;exemple de l&rsquo;<a href=\"https:\/\/radiona.org\/ulx3s\/\">ulx3s<\/a> qui permet de g\u00e9n\u00e9rer un signal HDMI diff\u00e9rentiel pour l&rsquo;int\u00e9grer dans le projet <a href=\"https:\/\/github.com\/Martoni\/HdmiCore\">HdmiCore<\/a> \u00e9crit en Chisel. L&rsquo;objectif \u00e9tant de porter le projet <a href=\"https:\/\/github.com\/Martoni\/HdmiCore\">HdmiCore<\/a> sur la plate-forme ulx3s en restant dans du pure Chisel.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Installation de l&rsquo;outil<\/h2>\n\n\n\n<p>Toutes les caract\u00e9ristiques et limitations du convertisseur sont donn\u00e9es sur<a href=\"https:\/\/github.com\/ovh\/sv2chisel\/blob\/master\/FEATURES_LIMITATIONS.md#sv2chisel-features--limitations\"> le wiki<\/a>. Pour l&rsquo;installer nous allons cloner le projet github. Le projet n&rsquo;en est pas \u00e0 sa version 1.0, il est sans doute pr\u00e9f\u00e9rable de \u00abtravailler\u00bb sur le main du git plut\u00f4t que sur une release.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ git clone https:\/\/github.com\/ovh\/sv2chisel.git\n$ cd sv2chisel<\/code><\/pre>\n\n\n\n<p>Les \u00e9tapes d&rsquo;installations depuis les sources sont donn\u00e9es dans le readme. Il faut publier localement sv2chisel ainsi que les \u00abhelpers\u00bb :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ sbt publishLocal<\/code><\/pre>\n\n\n\n<p>Cette commande fonctionne pas chez moi, je pensais na\u00efvement que c&rsquo;\u00e9tait la m\u00eame commande que celle consistant \u00e0 lancer sbt puis taper \u00abpublishLocal\u00bb mais non \ud83d\ude09<\/p>\n\n\n\n<p>Donc pour publier localement, on fera plut\u00f4t comme recommand\u00e9 dans le readme :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ sbt\nsbt:sv2chisel> publishLocal\nsbt:sv2chisel> helpers\/publishLocal\nsbt:sv2chisel> assembly<\/code><\/pre>\n\n\n\n<p>La commande \u00abassembly\u00bb g\u00e9n\u00e8re le fichier <strong>jar<\/strong> ex\u00e9cutable.<\/p>\n\n\n\n<p>Le binaire de l&rsquo;utilitaire est g\u00e9n\u00e9r\u00e9 dans le r\u00e9pertoire <code>utils\/bin\/<\/code> et se nomme tout simplement <strong>sv2chisel<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ .\/sv2chisel -help\nsv2chisel [Options] sv_files... or sv2chisel [Options] -c config_file\n\nCommons Options:\n    -l, --log-level &lt;error|warn|struct|info|debug|trace>\n                                     Logger verbosity level\n    -L, --class-log-level CLASS_NAME:&lt;error|warn|struct|info|debug|trace>\n                                     Logger verbosity level within given CLASS_NAME (useful for transforms)\n    -o, --emission-path PATH         Base emission path\n\nConfig File (prio over manually specified files):\n    -c, --config-file FILE           Yaml Configuration File\n\nManual command-line configuration\n    -i, --base-path PATH             Base path for files\n    -n, --name NAME                  Project name\n    -h, --help                       Show this message\n<\/pre>\n\n\n\n<p>Si l&rsquo;on regarde dans le fichier on trouve un simple lien vers l&rsquo;archive \u00abjar\u00bb se trouvant dans le m\u00eame r\u00e9pertoire:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ ls \nsv2chisel  sv2chisel.jar\n\n$ cat sv2chisel\n#!\/bin\/bash\n\npath=`dirname \"$0\"`\ncmd=\"java -cp ${path}\/sv2chisel.jar sv2chisel.Main ${@:1}\"<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Conversion<\/h2>\n\n\n\n<p>Pour convertir en Chisel, on peut simplement donner les noms des fichiers sources en arguments:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ .\/sv2chisel fake_differential.v\n&#91;log] ---- Processing project ----\n&#91;log] ############# Parsing fake_differential.v #############\n&#91;log] ######### Elapsed time for fake_differential.v #########\n&#91;log] # Lexing+Parsing Time : 335.206505 ms\n&#91;log] # Mapping to IR Time : 126.985877 ms\n&#91;log] ######### Executing 18 transforms #########\n&#91;log] ####### sv2chisel.transforms.CheckUseBeforeDecl #######\n&#91;log] # Elapsed time : 26.214516 ms\n&#91;log] ####### sv2chisel.transforms.CheckScopes #######\n&#91;log] # Elapsed time : 7.222317 ms\n&#91;log] ####### sv2chisel.transforms.CheckBlockingAssignments #######\n&#91;log] # Elapsed time : 1.448437 ms\n&#91;log] ####### sv2chisel.transforms.InferDefLogicClocks #######\n&#91;info] Registering a new clock clk_shift for module fake_differential (non blocking assignment) at fake_differential.v:3:0>>54:0\n&#91;warn] Unable to find module module ODDRX1F instanciated as ddr_p_instance in current module fake_differential for clock inference processing. at fake_differential.v:33:10>>41:11\n&#91;warn] Unable to find module module ODDRX1F instanciated as ddr_n_instance in current module fake_differential for clock inference processing. at fake_differential.v:42:10>>50:11\n&#91;log] # Elapsed time : 41.125895 ms\n&#91;log] ####### sv2chisel.transforms.PropagateClocks #######\n&#91;warn] Module ODDRX1F referenced by instance ddr_p_instance cannot be found in current design. Clock &amp; Reset management might be inaccurate. at fake_differential.v:33:10>>41:11\n&#91;warn] Module ODDRX1F referenced by instance ddr_n_instance cannot be found in current design. Clock &amp; Reset management might be inaccurate. at fake_differential.v:42:10>>50:11\n&#91;log] # Elapsed time : 1.878423 ms\n&#91;log] ####### sv2chisel.transforms.FlowReferences #######\n&#91;info] Declaring actual port directions for module fake_differential at fake_differential.v:5:2->8\n&#91;info] Running FlowReference Transform another time on module fake_differential at fake_differential.v:3:0>>54:0\n&#91;log] # Elapsed time : 28.311422 ms\n&#91;log] ####### sv2chisel.transforms.InferUInts #######\n&#91;info] Converting in_clock to UInt based on its usage in the module at fake_differential.v:7:9->11\n&#91;info] Converting tmds&#91;_] to UInt based on its usage in the module at fake_differential.v:11:10->12\n&#91;log] # Elapsed time : 30.181078 ms\n&#91;log] ####### sv2chisel.transforms.InferParamTypes #######\n&#91;log] # Elapsed time : 5.803376 ms\n&#91;log] ####### sv2chisel.transforms.TypeReferences #######\n&#91;critical] Unsupported Type 'Bool' for subindex expression 'out_n&#91;i]' at fake_differential.v:47:15->22\n&#91;log] # Elapsed time : 18.082934 ms\n&#91;log] ####### sv2chisel.transforms.LegalizeExpressions #######\n&#91;warn] Unknown remote type for port #2 (Q) of instance ddr_p_instance of module ODDRX1F: casting by reference by default at fake_differential.v:38:12->23\n&#91;critical] Unsupported Type 'Bool' for subindex expression 'out_n&#91;i]' at fake_differential.v:47:15->22\n&#91;warn] Unknown remote type for port #2 (Q) of instance ddr_n_instance of module ODDRX1F: casting by reference by default at fake_differential.v:47:12->23\n&#91;log] # Elapsed time : 29.292823 ms\n&#91;log] ####### sv2chisel.transforms.FixFunctionImplicitReturns #######\n&#91;log] # Elapsed time : 1.314473 ms\n&#91;log] ####### sv2chisel.transforms.NameInstancePorts #######\n&#91;log] # Elapsed time : 2.628666 ms\n&#91;log] ####### sv2chisel.transforms.RemovePatterns #######\n&#91;log] # Elapsed time : 4.862502 ms\n&#91;log] ####### sv2chisel.transforms.RemoveConcats #######\n&#91;log] # Elapsed time : 3.143862 ms\n&#91;log] ####### sv2chisel.transforms.AddDontCare #######\n&#91;log] # Elapsed time : 1.28653 ms\n&#91;log] ####### sv2chisel.transforms.LegalizeParamDefaults #######\n&#91;warn] Cannot find module ODDRX1F in current project at fake_differential.v:33:10>>41:11\n&#91;warn] Cannot find module ODDRX1F in current project at fake_differential.v:42:10>>50:11\n&#91;log] # Elapsed time : 4.072062 ms\n&#91;log] ####### sv2chisel.transforms.FixReservedNames #######\n&#91;log] # Elapsed time : 4.126536 ms\n&#91;log] ####### sv2chisel.transforms.ToCamelCase #######\n&#91;log] # Elapsed time : 0.830815 ms\n&#91;log] # Total Elapsed time running transforms : 216.675871 ms\n&#91;log] ######### EMISSION #########\n&#91;log] ######### CHISELIZING fake_differential.v #########\n&#91;info] At fake_differential.v:11: Emitting unpacked for node tmds\n&#91;info] At fake_differential.v:18: Emitting unpacked for node R_tmds_p\n&#91;info] At fake_differential.v:18: Emitting unpacked for node R_tmds_n\n&#91;log] # Elapsed time : 21.267262 ms\n&#91;log] ######### EMITTING to \/fake_differential.scala #########\nException in thread \"main\" java.io.FileNotFoundException: \/fake_differential.scala (Permission denied)\nat java.base\/java.io.FileOutputStream.open0(Native Method)\nat java.base\/java.io.FileOutputStream.open(FileOutputStream.java:291)\nat java.base\/java.io.FileOutputStream.(FileOutputStream.java:234)\nat java.base\/java.io.FileOutputStream.(FileOutputStream.java:123)\nat java.base\/java.io.FileWriter.(FileWriter.java:66)\nat sv2chisel.Emitter$.$anonfun$emitChisel$9(Emitter.scala:174)\nat sv2chisel.Utils$.time(Utils.scala:185)\nat sv2chisel.Emitter$.$anonfun$emitChisel$1(Emitter.scala:163)\nat scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:286)\nat scala.collection.mutable.ResizableArray.foreach(ResizableArray.scala:62)\nat scala.collection.mutable.ResizableArray.foreach$(ResizableArray.scala:55)\nat scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:49)\nat scala.collection.TraversableLike.map(TraversableLike.scala:286)\nat scala.collection.TraversableLike.map$(TraversableLike.scala:279)\nat scala.collection.AbstractTraversable.map(Traversable.scala:108)\nat sv2chisel.Emitter$.emitChisel(Emitter.scala:134)\nat sv2chisel.Driver$.emitChisel(Driver.scala:66)\nat sv2chisel.Main$.$anonfun$new$10(Main.scala:159)\nat scala.collection.immutable.List.foreach(List.scala:431)\nat sv2chisel.Main$.delayedEndpoint$sv2chisel$Main$1(Main.scala:157)\nat sv2chisel.Main$delayedInit$body.apply(Main.scala:55)\nat scala.Function0.apply$mcV$sp(Function0.scala:39)\nat scala.Function0.apply$mcV$sp$(Function0.scala:39)\nat scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:17)\nat scala.App.$anonfun$main$1$adapted(App.scala:80)\nat scala.collection.immutable.List.foreach(List.scala:431)\nat scala.App.main(App.scala:80)\nat scala.App.main$(App.scala:78)\nat sv2chisel.Main$.main(Main.scala:55)\nat sv2chisel.Main.main(Main.scala)<\/code><\/pre>\n\n\n\n<p>Apr\u00e8s de multiple messages plus ou moins critiques, la commande se termine sur une \u00e9tonnante erreur java de fichier non trouv\u00e9. Visiblement il faut lui fournir le path complet en argument (sans doute un bug) :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> .\/sv2chisel \/opt\/chiselmod\/sv2chisel\/utils\/bin\/fake_differential.v \n&#91;log]  ---- Processing project  ---- \n&#91;log] ############# Parsing \/opt\/chiselmod\/sv2chisel\/utils\/bin\/fake_differential.v #############\n&#91;log] ######### Elapsed time for \/opt\/chiselmod\/sv2chisel\/utils\/bin\/fake_differential.v #########\n&#91;log] # Lexing+Parsing Time : 337.962186 ms\n&#91;log] # Mapping to IR Time  : 123.022396 ms\n&#91;log] ######### Executing 18 transforms #########\n&#91;log]    ####### sv2chisel.transforms.CheckUseBeforeDecl #######\n&#91;log]    # Elapsed time : 24.704003 ms\n&#91;log]    ####### sv2chisel.transforms.CheckScopes #######\n&#91;log]    # Elapsed time : 6.588446 ms\n&#91;log]    ####### sv2chisel.transforms.CheckBlockingAssignments #######\n&#91;log]    # Elapsed time : 1.838544 ms\n&#91;log]    ####### sv2chisel.transforms.InferDefLogicClocks #######\n&#91;info] Registering a new clock `clk_shift` for module fake_differential (non blocking assignment) at \/opt\/chiselmod\/sv2chisel\/utils\/bin\/fake_differential.v:3:0>>54:0\n&#91;warn] Unable to find module module ODDRX1F instanciated as ddr_p_instance in current module fake_differential for clock inference processing. at \/opt\/chiselmod\/sv2chisel\/utils\/bin\/fake_differential.v:33:10>>41:11\n&#91;warn] Unable to find module module ODDRX1F instanciated as ddr_n_instance in current module fake_differential for clock inference processing. at \/opt\/chiselmod\/sv2chisel\/utils\/bin\/fake_differential.v:42:10>>50:11\n&#91;log]    # Elapsed time : 37.088031 ms\n&#91;log]    ####### sv2chisel.transforms.PropagateClocks #######\n&#91;warn] Module ODDRX1F referenced by instance ddr_p_instance cannot be found in current design. Clock &amp; Reset management might be inaccurate. at \/opt\/chiselmod\/sv2chisel\/utils\/bin\/fake_differential.v:33:10>>41:11\n&#91;warn] Module ODDRX1F referenced by instance ddr_n_instance cannot be found in current design. Clock &amp; Reset management might be inaccurate. at \/opt\/chiselmod\/sv2chisel\/utils\/bin\/fake_differential.v:42:10>>50:11\n&#91;log]    # Elapsed time : 1.73635 ms\n&#91;log]    ####### sv2chisel.transforms.FlowReferences #######\n&#91;info] Declaring actual port directions for module fake_differential at \/opt\/chiselmod\/sv2chisel\/utils\/bin\/fake_differential.v:5:2->8\n&#91;info] Running FlowReference Transform another time on module fake_differential at \/opt\/chiselmod\/sv2chisel\/utils\/bin\/fake_differential.v:3:0>>54:0\n&#91;log]    # Elapsed time : 25.221955 ms\n&#91;log]    ####### sv2chisel.transforms.InferUInts #######\n&#91;info] Converting in_clock to UInt based on its usage in the module at \/opt\/chiselmod\/sv2chisel\/utils\/bin\/fake_differential.v:7:9->11\n&#91;info] Converting tmds&#91;_] to UInt based on its usage in the module at \/opt\/chiselmod\/sv2chisel\/utils\/bin\/fake_differential.v:11:10->12\n&#91;log]    # Elapsed time : 29.58874 ms\n&#91;log]    ####### sv2chisel.transforms.InferParamTypes #######\n&#91;log]    # Elapsed time : 5.646461 ms\n&#91;log]    ####### sv2chisel.transforms.TypeReferences #######\n&#91;critical] Unsupported Type 'Bool' for subindex expression 'out_n&#91;i]' at \/opt\/chiselmod\/sv2chisel\/utils\/bin\/fake_differential.v:47:15->22\n&#91;log]    # Elapsed time : 18.257447 ms\n&#91;log]    ####### sv2chisel.transforms.LegalizeExpressions #######\n&#91;warn] Unknown remote type for port #2 (Q) of instance ddr_p_instance of module ODDRX1F: casting by reference by default at \/opt\/chiselmod\/sv2chisel\/utils\/bin\/fake_differential.v:38:12->23\n&#91;critical] Unsupported Type 'Bool' for subindex expression 'out_n&#91;i]' at \/opt\/chiselmod\/sv2chisel\/utils\/bin\/fake_differential.v:47:15->22\n&#91;warn] Unknown remote type for port #2 (Q) of instance ddr_n_instance of module ODDRX1F: casting by reference by default at \/opt\/chiselmod\/sv2chisel\/utils\/bin\/fake_differential.v:47:12->23\n&#91;log]    # Elapsed time : 21.168114 ms\n&#91;log]    ####### sv2chisel.transforms.FixFunctionImplicitReturns #######\n&#91;log]    # Elapsed time : 0.631086 ms\n&#91;log]    ####### sv2chisel.transforms.NameInstancePorts #######\n&#91;log]    # Elapsed time : 1.467731 ms\n&#91;log]    ####### sv2chisel.transforms.RemovePatterns #######\n&#91;log]    # Elapsed time : 5.09245 ms\n&#91;log]    ####### sv2chisel.transforms.RemoveConcats #######\n&#91;log]    # Elapsed time : 2.749951 ms\n&#91;log]    ####### sv2chisel.transforms.AddDontCare #######\n&#91;log]    # Elapsed time : 1.251281 ms\n&#91;log]    ####### sv2chisel.transforms.LegalizeParamDefaults #######\n&#91;warn] Cannot find module ODDRX1F in current project at \/opt\/chiselmod\/sv2chisel\/utils\/bin\/fake_differential.v:33:10>>41:11\n&#91;warn] Cannot find module ODDRX1F in current project at \/opt\/chiselmod\/sv2chisel\/utils\/bin\/fake_differential.v:42:10>>50:11\n&#91;log]    # Elapsed time : 3.092851 ms\n&#91;log]    ####### sv2chisel.transforms.FixReservedNames #######\n&#91;log]    # Elapsed time : 4.132691 ms\n&#91;log]    ####### sv2chisel.transforms.ToCamelCase #######\n&#91;log]    # Elapsed time : 0.890969 ms\n&#91;log] # Total Elapsed time running transforms : 195.82181 ms\n&#91;log] ######### EMISSION #########\n&#91;log] ######### CHISELIZING \/opt\/chiselmod\/sv2chisel\/utils\/bin\/fake_differential.v #########\n&#91;info] At \/opt\/chiselmod\/sv2chisel\/utils\/bin\/fake_differential.v:11: Emitting unpacked for node tmds\n&#91;info] At \/opt\/chiselmod\/sv2chisel\/utils\/bin\/fake_differential.v:18: Emitting unpacked for node R_tmds_p\n&#91;info] At \/opt\/chiselmod\/sv2chisel\/utils\/bin\/fake_differential.v:18: Emitting unpacked for node R_tmds_n\n&#91;log] # Elapsed time : 25.374274 ms\n&#91;log] ######### EMITTING to \/\/opt\/chiselmod\/sv2chisel\/utils\/bin\/fake_differential.scala #########\n&#91;log] # Elapsed time : 17.429649 ms<\/code><\/pre>\n\n\n\n<p>Il y a sans doute beaucoup de chose a parametrer aux petits oignons pour bien utiliser l&rsquo;outils, mais le r\u00e9sultat \u00aben l&rsquo;\u00e9tat\u00bb est d\u00e9j\u00e0 assez int\u00e9ressant (commentaires <em>FLF<\/em> ajout\u00e9s):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package \/\/ FLF: \u00e0 rajouter \u00e0 la main ?\n\/\/ FLF: on comprend pourquoi il voulait un path complet,\n\/\/      il le prend pour le nom du package\npackage .opt.chiselmod.sv2chisel.utils.bin\n\nimport chisel3._\n\/\/ FLF: commentaires gard\u00e9s, bien.\n\/\/ DDR mode uses Lattice ECP5 vendor-specific module ODDRX1F\n\nclass fake_differential() extends Module { \/\/ used only in DDR mode\n  \/\/ &#91;1:0]:DDR &#91;0]:SDR TMDS\n  val in_clock = IO(Input(UInt(2.W)))\n  val in_red = IO(Input(Bool()))\n  val in_green = IO(Input(Bool()))\n  val in_blue = IO(Input(Bool()))\n  \/\/ &#91;3]:clock &#91;2]:red &#91;1]:green &#91;0]:blue \n  val out_p = IO(Output(Vec(4, Bool())))\n  val out_n = IO(Output(Bool()))\n\/\/ FLF: hmm, j'aurais pas traduit un tableau \u00abwire\u00bb par une Mem() \n\/\/      chisel, pas s\u00fbr que \u00e7a marche bien cette affaire.\n  val tmds = Mem(4,UInt(2.W)) \n  tmds(3) := in_clock\n  tmds(2) := in_red\n  tmds(1) := in_green\n  tmds(0) := in_blue\n\n  \/\/ register stage to improve timing of the fake differential\n  val R_tmds_p = Mem(4,Vec(2, Bool())) \n  val R_tmds_n = Mem(4,Vec(2, Bool())) \n  \/\/ genvar i;\n  for(i &lt;- 0 until 4){\n    R_tmds_p(i) := tmds(i).asBools\n    R_tmds_n(i) := ( ~tmds(i)).asBools\n  }\n\n  \/\/ output SDR\/DDR to fake differential\n\n  \/\/ FLF: les generate sont d\u00e9tect\u00e9 et traduit \u00e9galement.\n  \/\/ genvar i;\n  for(i &lt;- 0 until 4){\n    \/\/ FLF: connexion des primitives sans broncher\n    \/\/      Il faudra tout de m\u00eame inclure la d\u00e9finition\n    \/\/      de la blackbox \u00e0 la main par la suite (import)\n    val ddr_p_instance = Module(new ODDRX1F)\n    ddr_p_instance.D0 := R_tmds_p(i)(0)\n    ddr_p_instance.D1 := R_tmds_p(i)(1)\n    out_p(i) := ddr_p_instance.Q.asTypeOf(out_p(i))\n    ddr_p_instance.SCLK := clock\n    ddr_p_instance.RST := 0.U\n    val ddr_n_instance = Module(new ODDRX1F)\n    ddr_n_instance.D0 := R_tmds_n(i)(0)\n    ddr_n_instance.D1 := R_tmds_n(i)(1)\n    out_n(i) := ddr_n_instance.Q.asTypeOf(out_n(i))\n    ddr_n_instance.SCLK := clock\n    ddr_n_instance.RST := 0.U\n  }\n\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>Visiblement, le code g\u00e9n\u00e9r\u00e9 doit \u00eatre pass\u00e9 en revue par un ou une humaine histoire de corriger quelques impr\u00e9cisions.<\/p>\n\n\n\n<p>Mais cette relecture est facile, le code est tr\u00e8s lisible et bien indent\u00e9. On retrouve les noms des signaux, variables, registres, modules Verilog.  On est loin des bouillies de conversion o\u00f9 le code g\u00e9n\u00e9r\u00e9 ressemble plus \u00e0 un binaire compil\u00e9 qu&rsquo;\u00e0 un code source \u00abversionnable\u00bb. Et cette saine relecture est de toute mani\u00e8re indispensable si l&rsquo;on souhaite se reposer sur ce nouveau code dans la suite de son projet.<\/p>\n\n\n\n<p>C&rsquo;est un outil qui va vite devenir indispensable lorsque le besoin de convertion de code open-source se fera sentir. Et c&rsquo;est une belle passerelle  pour tous les habitu\u00e9s du Verilog qui souhaiteraient se lancer dans ce langage de haut niveau qu&rsquo;est Chisel.<\/p>\n\n\n\n<p>Des dire de l&rsquo;\u00e9quipe, l&rsquo;outil a \u00e9t\u00e9 test\u00e9 avec succ\u00e8s sur le code du processeur RISC-V <a href=\"https:\/\/github.com\/YosysHQ\/picorv32\">PicoRV32<\/a> d\u00e9velopp\u00e9 par Claire Clifford (autrice de Yosys) que l&rsquo;on retrouve un peu partout dans les projets open-source hardware.<\/p>\n\n\n\n<p>C&rsquo;est \u00e9galement une surprise de voir que ce projet est n\u00e9 au sein du laboratoire <strong>OVHCloud<\/strong>. O\u00f9 l&rsquo;on d\u00e9couvre que le fleurons du Claude fran\u00e7ais (cocorico) finance la recherche sur le mat\u00e9riel libre.  Ceux qui ont besoin d&rsquo;un article plus acad\u00e9mique pour d\u00e9couvrir l&rsquo;outil iront lire le papier de l&rsquo;\u00e9quipe <a href=\"https:\/\/hal.archives-ouvertes.fr\/hal-02949112\/document\">ici<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Le monde du FPGA (et de l&rsquo;ASIC) regorge aujourd&rsquo;hui de langages de description mat\u00e9riel. Au Verilog et VHDL s&rsquo;ajoute maintenant tout un tas de langages comme Migen, Clash, BlueSpec, Amaranth, Chisel, SpinalHDL, Silice, &#8230; et j&rsquo;en oublie plein. Tous ces langages permettent de g\u00e9n\u00e9rer du Verilog. Les possibilit\u00e9 de conversion de VHDL vers Verilog ne &hellip; <a href=\"http:\/\/www.fabienm.eu\/flf\/sv2chisel-le-convertisseur-systemverilog-vers-chisel\/\" class=\"more-link\">Continuer la lecture de <span class=\"screen-reader-text\">sv2chisel, le convertisseur (System)Verilog vers Chisel<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","footnotes":""},"categories":[1],"tags":[57,216,30],"class_list":["post-1952","post","type-post","status-publish","format-standard","hentry","category-non-classe","tag-chisel","tag-ovhcloud","tag-verilog"],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false,"post-thumbnail":false},"uagb_author_info":{"display_name":"Fabien Marteau","author_link":"http:\/\/www.fabienm.eu\/flf\/author\/admin\/"},"uagb_comment_info":0,"uagb_excerpt":"Le monde du FPGA (et de l&rsquo;ASIC) regorge aujourd&rsquo;hui de langages de description mat\u00e9riel. Au Verilog et VHDL s&rsquo;ajoute maintenant tout un tas de langages comme Migen, Clash, BlueSpec, Amaranth, Chisel, SpinalHDL, Silice, &#8230; et j&rsquo;en oublie plein. Tous ces langages permettent de g\u00e9n\u00e9rer du Verilog. Les possibilit\u00e9 de conversion de VHDL vers Verilog ne\u2026","_links":{"self":[{"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/posts\/1952","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/comments?post=1952"}],"version-history":[{"count":12,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/posts\/1952\/revisions"}],"predecessor-version":[{"id":2018,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/posts\/1952\/revisions\/2018"}],"wp:attachment":[{"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/media?parent=1952"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/categories?post=1952"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/tags?post=1952"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}