{"action":"opened","issue":{"url":"https://api.github.com/repos/UCSBarchlab/PyRTL/issues/200","repository_url":"https://api.github.com/repos/UCSBarchlab/PyRTL","labels_url":"https://api.github.com/repos/UCSBarchlab/PyRTL/issues/200/labels{/name}","comments_url":"https://api.github.com/repos/UCSBarchlab/PyRTL/issues/200/comments","events_url":"https://api.github.com/repos/UCSBarchlab/PyRTL/issues/200/events","html_url":"https://github.com/UCSBarchlab/PyRTL/issues/200","id":166677737,"number":200,"title":"MemBlock Asynchronous=True Does not Work","user":{"login":"masoug","id":468384,"avatar_url":"https://avatars.githubusercontent.com/u/468384?v=3","gravatar_id":"","url":"https://api.github.com/users/masoug","html_url":"https://github.com/masoug","followers_url":"https://api.github.com/users/masoug/followers","following_url":"https://api.github.com/users/masoug/following{/other_user}","gists_url":"https://api.github.com/users/masoug/gists{/gist_id}","starred_url":"https://api.github.com/users/masoug/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/masoug/subscriptions","organizations_url":"https://api.github.com/users/masoug/orgs","repos_url":"https://api.github.com/users/masoug/repos","events_url":"https://api.github.com/users/masoug/events{/privacy}","received_events_url":"https://api.github.com/users/masoug/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2016-07-20T20:45:35Z","updated_at":"2016-07-20T20:45:35Z","closed_at":null,"body":"Given this pyrtl mem test code:\r\n```\r\nimport sys\r\nimport pyrtl\r\nfrom pyrtl import *\r\n\r\n# *NOTE* Requires memory sanity check to be disabled!\r\n\r\nmem_direct = MemBlock(bitwidth=32, addrwidth=8, name='mem_direct')\r\nmem_combo = MemBlock(bitwidth=32, addrwidth=8, name='mem_combo')\r\nmem_register = MemBlock(bitwidth=32, addrwidth=8, name='mem_register', asynchronous=True)\r\n\r\nWE = MemBlock.EnabledWrite\r\nwe = Input(2, 'we')\r\n\r\ncombo_input1 = Input(8, \"combo_input1\")\r\ncombo_input2 = Input(8, \"combo_input2\")\r\ndirect_addr = Input(8, \"direct_addr\")\r\nwrite_data = Input(32, \"write_data\")\r\n\r\nmem_direct_out = Output(32, \"mem_direct_output\")\r\nmem_combo_out = Output(32, \"mem_combo_output\")\r\nmem_register_out = Output(32, \"mem_register_output\")\r\n\r\n# address memory directly from input\r\nmem_direct_out <<= mem_direct[direct_addr]\r\nmem_direct[direct_addr] <<= WE(write_data, we == 0)\r\n\r\n# address memory from combo logic\r\nmem_combo_out <<= mem_combo[(combo_input1+combo_input2)[0:8]]\r\nmem_combo[(combo_input1+combo_input2)[0:8]] <<= WE(write_data, we == 1)\r\n\r\n# address memory from reg\r\naddr_register = Register(8, \"addr_register\")\r\naddr_register.next <<= direct_addr\r\nmem_register_out <<= mem_register[addr_register]\r\nmem_register[addr_register] <<= WE(write_data, we == 2)\r\n\r\noptimize()\r\n\r\n# compile to verilog\r\nwith open('hardware.v', 'w') as fp:\r\n    OutputToVerilog(fp)\r\n    \r\n# run pyrtl simulation\r\nsimvals = {\r\n    'we':               \"000000000333333333111111111333333333222222222333333333\",\r\n    'combo_input1':     \"000000000000000000123456789123456789000000000000000000\",\r\n    'combo_input2':     \"000000000000000000123456789123456789000000000000000000\",\r\n    'direct_addr':      \"123456789123456789000000000000000000123456789123456789\",\r\n    'write_data':       \"123456789000000000123456789000000000123456789000000000\"\r\n}\r\n\r\nsim_trace = pyrtl.SimulationTrace()\r\nsim = pyrtl.Simulation(tracer=sim_trace)\r\nfor cycle in range(len(simvals['we'])):\r\n    sim.step({k: int(v[cycle]) for k, v in simvals.items()})\r\n\r\nwith open('trace.vcd', 'w') as fp:\r\n    sim_trace.print_vcd(fp)\r\n```\r\n\r\nyields this verilog output: \r\n\r\n```\r\n// Generated automatically via PyRTL\r\n// As one initial test of synthesis, map to FPGA with:\r\n//   yosys -p \"synth_xilinx -top toplevel\" thisfile.v\r\n\r\nmodule toplevel(combo_input2, we, direct_addr, write_data, mem_direct_output, combo_input1, mem_combo_output, mem_register_output, clk);\r\n    input[1:0] we;\r\n    input[7:0] combo_input2;\r\n    input[7:0] combo_input1;\r\n    input[7:0] direct_addr;\r\n    input[31:0] write_data;\r\n    input clk;\r\n    output[31:0] mem_direct_output;\r\n    output[31:0] mem_combo_output;\r\n    output[31:0] mem_register_output;\r\n\r\n    reg[7:0] addr_register;\r\n    reg[31:0] tmp6;\r\n    wire const_0_0;\r\n    wire[1:0] const_4_2;\r\n    wire tmp3;\r\n    wire[8:0] tmp4;\r\n    wire const_1_0;\r\n    wire tmp1;\r\n    wire[1:0] tmp2;\r\n    wire[7:0] tmp5;\r\n    reg[31:0] tmp0;\r\n    wire tmp13;\r\n    wire const_2_1;\r\n    wire tmp11;\r\n    wire const_3_0;\r\n    wire[1:0] tmp10;\r\n    reg[31:0] tmp12;\r\n\r\n    reg[31:0] mem_1[255:0];\r\n    reg[31:0] mem_2[255:0];\r\n    reg[31:0] mem_0[255:0];\r\n\r\n    assign const_2_1 = 1;\r\n    assign const_1_0 = 0;\r\n    assign const_3_0 = 0;\r\n    assign const_4_2 = 2;\r\n    assign const_0_0 = 0;\r\n    assign tmp10 = {tmp1, const_2_1};\r\n    assign tmp4 = combo_input1 + combo_input2;\r\n    assign tmp5 = {tmp4[7], tmp4[6], tmp4[5], tmp4[4], tmp4[3], tmp4[2], tmp4[1], tmp4[0]};\r\n    always @( posedge clk )\r\n    begin\r\n        tmp12 <= mem_2[addr_register];\r\n    end\r\n    assign mem_register_output = tmp12;\r\n    assign mem_combo_output = tmp6;\r\n    assign mem_direct_output = tmp0;\r\n    always @( posedge clk )\r\n    begin\r\n        tmp6 <= mem_1[tmp5];\r\n    end\r\n    assign tmp1 = {const_1_0};\r\n    assign tmp2 = {tmp1, const_0_0};\r\n    assign tmp11 = we == tmp10;\r\n    assign tmp13 = we == const_4_2;\r\n    assign tmp3 = we == tmp2;\r\n    always @( posedge clk )\r\n    begin\r\n        tmp0 <= mem_0[direct_addr];\r\n    end\r\n\r\n    always @( posedge clk )\r\n    begin\r\n        if (tmp3) begin\r\n                mem_0[direct_addr] <= write_data;\r\n        end\r\n        addr_register <= direct_addr;\r\n        if (tmp11) begin\r\n                mem_1[tmp5] <= write_data;\r\n        end\r\n        if (tmp13) begin\r\n                mem_2[addr_register] <= write_data;\r\n        end\r\n    end\r\nendmodule\r\n```\r\n\r\nnotice that although i set one of the memories to be asynchronous, all of the verilog output memories are still under posedge blocks. To my knowledge, async mems in verilog are not supposed to be under posedge blocks."}}
{"actor":{"display_login":"masoug"}}