onilink_

Lua demo

Jan 16th, 2023
1,072
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.56 KB | None | 0 0
  1.  
  2. local Input = {
  3.     Clk1 = 1,
  4.     Clk2 = 2,
  5.     Sync = 3,
  6.     D0 = 4,
  7.     D1 = 5,
  8.     D2 = 6,
  9.     D3 = 7,
  10.     Test = 8,
  11.     Poc  = 9
  12. }
  13.  
  14. local Output = {
  15.     CM_Rom = 1,
  16.     CM_Ram0 = 2,
  17.     CM_Ram1 = 3,
  18.     CM_Ram2 = 4,
  19.     CM_Ram3 = 5
  20. }
  21.  
  22. local sim = {}
  23.  
  24. function sim.create(editor)
  25.     local proxy = editor:proxy()
  26.    
  27.     -- get nodes associated to I/Os
  28.     sim.in_nodes = {
  29.         editor:findNodeInput("CLK1"),
  30.         editor:findNodeInput("CLK2"),
  31.         editor:findNodeInput("SYNC"),
  32.         editor:findNodeInput("D0"),
  33.         editor:findNodeInput("D1"),
  34.         editor:findNodeInput("D2"),
  35.         editor:findNodeInput("D3"),
  36.         editor:findNodeInput("TEST"),
  37.         editor:findNodeInput("POC"),
  38.     }
  39.    
  40.     sim.out_nodes = {
  41.         editor:findNodeOutput("ROM"),
  42.         editor:findNodeOutput("RAM0"),
  43.         editor:findNodeOutput("RAM1"),
  44.         editor:findNodeOutput("RAM2"),
  45.         editor:findNodeOutput("RAM3")
  46.     }
  47.    
  48.     -- get nodes associated to registers
  49.     local ctx = editor:context()
  50.     sim.reg_nodes = {}
  51.     for r=1, 16 do
  52.         sim.reg_nodes[r] = {}
  53.         for n=1, 4 do
  54.             local name = string.format("TR%x%x", r-1, n-1):upper()
  55.             sim.reg_nodes[r][n] = editor:findNode(ctx, name, ComponentType.Nmos, 0)
  56.         end
  57.     end
  58.    
  59.     sim.acc_nodes = {}
  60.     for n=1, 4 do
  61.         sim.acc_nodes[n] = editor:findNode(ctx, string.format("T_ACC%d", n-1), ComponentType.Nmos, 0)
  62.     end
  63.    
  64.     sim.carry_node = editor:findNode(ctx, "T_CARRY", ComponentType.Nmos, 0)
  65.    
  66.    
  67.     sim.timer = 0
  68.     sim.timer_max = 2
  69.     sim.popup = true
  70.     sim.paused = true
  71.     sim.win2_x = 0
  72.     sim.win2_y = 0
  73.    
  74.     sim.updates = {}
  75.     sim.inputs = {}
  76.     sim.outputs = {}
  77.    
  78.     -- program: fill all registers to FF with FIM
  79.     sim.program = {
  80.         0x20, 0xFF, 0x22, 0xFF, 0x24, 0xFF,
  81.         0x26, 0xFF, 0x28, 0xFF, 0x2A, 0xFF,
  82.         0x2C, 0xFF, 0x2E, 0xFF}
  83.    
  84. --     sim.program = { 0x20, 0x07, 0x81, 0x81, 0x81 }
  85.    
  86.     -- generate rom data from object code
  87.     sim.rom_data = {}
  88.     for i=1, #sim.program do
  89.         table.insert(sim.rom_data, bit32_band(bit32_bsr(sim.program[i], 4), 0xF))
  90.         table.insert(sim.rom_data, bit32_band(sim.program[i], 0xF))
  91.     end
  92.    
  93.     sim.runInitSequence(proxy)
  94. end
  95.  
  96. function sim.runInitSequence(proxy)
  97.    
  98.     -- initialize inputs to LOW
  99.     for i=1, #sim.in_nodes do
  100.         proxy:write(sim.in_nodes[i], false)
  101.     end
  102.     proxy:stabilize()
  103.    
  104.     for i=1, Input.Poc do
  105.         sim.updates[i] = false
  106.         sim.inputs[i] = false
  107.     end
  108.    
  109.     for i=1, Output.CM_Ram3 do
  110.         sim.outputs[i] = false
  111.     end
  112.    
  113.     sim.cmrom = false
  114.     sim.cmrom_prev = false
  115.    
  116.     sim.read_rom   = false
  117.     sim.read_addr  = false
  118.     sim.read_cycle = 0
  119.     sim.rom_cursor = 0
  120.     sim.read_addr_cycle = 0
  121.     sim.cycle = 0
  122.    
  123.     for k=1, 1100 do
  124.         sim.inputs[Input.Clk1] = (sim.cycle+3) % 4 == 0
  125.         sim.inputs[Input.Clk2] = (sim.cycle+1) % 4 == 0
  126.         sim.inputs[Input.Sync] = sim.sync(32)
  127.         sim.inputs[Input.Test] = true
  128.         sim.inputs[Input.Poc ] = (sim.cycle < 1099)
  129.        
  130.         sim.cycle = sim.cycle+1
  131.        
  132.         for i=1, #sim.in_nodes do
  133.             proxy:write(sim.in_nodes[i], sim.inputs[i])
  134.         end
  135.         proxy:simulate()
  136.     end
  137. end
  138.  
  139. function sim.simulateOneClockPhase(proxy)
  140.    
  141.     sim.cmrom = proxy:read(sim.out_nodes[Output.CM_Rom])
  142.     sim.inputs[Input.D0] = proxy:read(sim.in_nodes[Input.D0])
  143.     sim.inputs[Input.D1] = proxy:read(sim.in_nodes[Input.D1])
  144.     sim.inputs[Input.D2] = proxy:read(sim.in_nodes[Input.D2])
  145.     sim.inputs[Input.D3] = proxy:read(sim.in_nodes[Input.D3])
  146.    
  147.     sim.updateSignals()
  148.     sim.signalsToUpdate()
  149.    
  150.     for i=1, #sim.in_nodes do
  151.         if(sim.updates[i]) then
  152.             proxy:write(sim.in_nodes[i], sim.inputs[i])
  153.         else
  154.             proxy:clear(sim.in_nodes[i])
  155.         end
  156.     end
  157.    
  158.     proxy:simulate()
  159. end
  160.  
  161. function sim.simulateOneInstructionCycle(proxy)
  162.     for i=1, 32 do
  163.         sim.simulateOneClockPhase(proxy)
  164.     end
  165. end
  166.  
  167. function sim.updateSignals()
  168.     local pp_sync = sim.sync(30)
  169.     local p_sync  = sim.sync(31)
  170.    
  171.     sim.inputs[Input.Clk1] = (sim.cycle+3) % 4 == 0
  172.     sim.inputs[Input.Clk2] = (sim.cycle+1) % 4 == 0
  173.     sim.inputs[Input.Sync] = sim.sync(32)
  174.     sim.inputs[Input.Test] = false
  175.     sim.inputs[Input.Poc ] = false
  176.    
  177.     if(sim.cmrom_prev and not sim.cmrom) then
  178.         sim.inputs[Input.D0] = true
  179.         sim.inputs[Input.D1] = true
  180.         sim.inputs[Input.D2] = true
  181.         sim.inputs[Input.D3] = true
  182.         sim.read_rom = true
  183.         sim.read_cycle = 0
  184.     end
  185.    
  186.     if(sim.read_rom) then
  187.         local rom_index = 1 + sim.rom_cursor*2 + ((sim.read_cycle >= 4) and 1 or 0)
  188.         local data = 0
  189.         if(rom_index <= #sim.rom_data) then
  190.             data = sim.rom_data[rom_index]
  191.         end
  192.        
  193.         sim.inputs[Input.D0] = bit32_band(bit32_bsr(data, 0), 1) ~= 0
  194.         sim.inputs[Input.D1] = bit32_band(bit32_bsr(data, 1), 1) ~= 0
  195.         sim.inputs[Input.D2] = bit32_band(bit32_bsr(data, 2), 1) ~= 0
  196.         sim.inputs[Input.D3] = bit32_band(bit32_bsr(data, 3), 1) ~= 0
  197.        
  198.         if(sim.read_cycle == 10) then
  199.             sim.read_rom = false
  200.         else
  201.             sim.read_cycle = sim.read_cycle + 1
  202.         end
  203.     end
  204.    
  205.     if(pp_sync and  not p_sync) then
  206.         sim.read_addr = true
  207.         sim.read_addr_cycle = 0
  208.         sim.rom_cursor = 0
  209.     end
  210.    
  211.     if(sim.read_addr) then
  212.         if(sim.read_addr_cycle % 4 == 0) then
  213.             local w = 0
  214.             w = bit32_bor(w, bit32_bsl(sim.inputs[Input.D0], 0))
  215.             w = bit32_bor(w, bit32_bsl(sim.inputs[Input.D1], 1))
  216.             w = bit32_bor(w, bit32_bsl(sim.inputs[Input.D2], 2))
  217.             w = bit32_bor(w, bit32_bsl(sim.inputs[Input.D3], 3))
  218.            
  219.             sim.rom_cursor = bit32_bor(bit32_bsl(sim.rom_cursor, 4), w)
  220.            
  221.             if(sim.read_addr_cycle >= 8) then
  222.                 sim.read_addr = false
  223.                 sim.rom_cursor =
  224.                     bit32_bor(
  225.                       bit32_bor(
  226.                         bit32_bsr(bit32_band(sim.rom_cursor, 0xF00), 8),
  227.                         bit32_band(sim.rom_cursor, 0x0F0)),
  228.                         bit32_bsr(bit32_band(sim.rom_cursor, 0x00F), 8));
  229.                
  230.             end
  231.         end
  232.        
  233.         sim.read_addr_cycle = sim.read_addr_cycle + 1
  234.     end
  235.    
  236.     sim.cycle = sim.cycle + 1
  237.    
  238.     sim.cmrom_prev = sim.cmrom
  239.    
  240. end
  241.  
  242. function sim.signalsToUpdate()
  243.     sim.updates[Input.Clk1] = true
  244.     sim.updates[Input.Clk2] = true
  245.     sim.updates[Input.Sync] = true
  246.    
  247.     if(sim.read_rom) then
  248.         sim.updates[Input.D0] = true
  249.         sim.updates[Input.D1] = true
  250.         sim.updates[Input.D2] = true
  251.         sim.updates[Input.D3] = true
  252.     else
  253.         sim.updates[Input.D0] = false
  254.         sim.updates[Input.D1] = false
  255.         sim.updates[Input.D2] = false
  256.         sim.updates[Input.D3] = false
  257.     end
  258.    
  259.     sim.updates[Input.Test] = true
  260.     sim.updates[Input.Poc ] = true
  261. end
  262.  
  263. function sim.update(editor, dt)
  264.     local proxy = editor:proxy()
  265.    
  266.     sim.ui_sim(editor, proxy)
  267.     sim.ui_registers(proxy)
  268.    
  269.     if(sim.paused or sim.wait(dt)) then
  270.         return
  271.     end
  272.    
  273.     local proxy = editor:proxy()
  274.     sim.simulateOneClockPhase(proxy)
  275. end
  276.  
  277. function sim.wait(dt)
  278.     sim.timer = sim.timer - dt
  279.     if(sim.timer > 0) then
  280.         return true
  281.     end
  282.     sim.timer = sim.timer_max
  283.     return false
  284. end
  285.  
  286. function sim.sync(n)
  287.     if(sim.cycle > 4) then
  288.         return math.floor((sim.cycle + n)/4) % 8 == 0
  289.     else
  290.         return false
  291.     end
  292. end
  293.  
  294. -- interface
  295. function sim.ui_sim(editor, proxy)
  296.    
  297.     ImGui.SetNextWindowPos(16, 16)
  298.    
  299.     local open, should_draw = ImGui.Begin("Simulation", true,
  300.         ImGuiWindowFlags.NoResize +
  301.         ImGuiWindowFlags.AlwaysAutoResize +
  302.         ImGuiWindowFlags.NoTitleBar +
  303.         ImGuiWindowFlags.NoSavedSettings)
  304.    
  305.     if(should_draw)
  306.     then
  307.         if(sim.paused) then
  308.             if(ImGui.Button("Play")) then
  309.                 sim.paused = false
  310.             end
  311.         else
  312.             if(ImGui.Button("Pause")) then
  313.                 sim.paused = true
  314.             end
  315.         end
  316.        
  317.         if(ImGui.Button("Reset")) then
  318.             proxy:coldReset()
  319.             sim.runInitSequence(proxy)
  320.             sim.paused = true
  321.         end
  322.        
  323.         if(ImGui.Button("Clock")) then
  324.             sim.simulateOneClockPhase(proxy)
  325.             sim.paused = true
  326.         end
  327.        
  328.         if(ImGui.Button("Cycle")) then
  329.             sim.simulateOneInstructionCycle(proxy)
  330.             sim.paused = true
  331.         end
  332.        
  333.         if(ImGui.Button("Stop")) then
  334.             editor:stopSimulation()
  335.         end
  336.     end
  337.    
  338.     local size_x, size_y = ImGui.GetWindowSize()
  339.     local pos_x, pos_y = ImGui.GetWindowPos()
  340.     sim.win2_x = pos_x + size_x + 8
  341.    
  342.     ImGui.End()
  343. end
  344.  
  345. function sim.compute_register(proxy, nodes)
  346.     local temp = 0
  347.     for n=1, 4 do
  348.         local bit = proxy:read(nodes[n]) and 1 or 0
  349.         temp = temp + bit32_bsl(bit, n-1)
  350.     end
  351.     return temp
  352. end
  353.  
  354. function sim.ui_registers(proxy)
  355.    
  356.     ImGui.SetNextWindowPos(sim.win2_x, 16)
  357.    
  358.     local open, should_draw = ImGui.Begin("Watch", true,
  359.         ImGuiWindowFlags.NoResize +
  360.         ImGuiWindowFlags.AlwaysAutoResize +
  361.         ImGuiWindowFlags.NoSavedSettings)
  362.    
  363.     if(should_draw)
  364.     then
  365.        
  366.         local reg = {}
  367.         for r=1, 16 do
  368.             reg[r] = sim.compute_register(proxy, sim.reg_nodes[r])
  369.         end
  370.        
  371.         for i=1, 4 do
  372.             local i2 = 2*(i-1)
  373.             ImGui.Text(string.format("R%xR%x", i2, i2+1))
  374.             ImGui.SameLine()
  375.             ImGui.Text(string.format("%x%x", reg[i2+1], reg[i2+2]):upper())
  376.            
  377.             ImGui.SameLine()
  378.             ImGui.Text(string.format("R%xR%x", i2+8, i2+9):upper())
  379.             ImGui.SameLine()
  380.             ImGui.Text(string.format("%x%x", reg[i2+9], reg[i2+10]):upper())
  381.         end
  382.        
  383.         local acc = sim.compute_register(proxy, sim.acc_nodes)
  384.         ImGui.Text("Accumulator:")
  385.         ImGui.SameLine()
  386.         ImGui.Text(string.format("%d", acc))
  387.        
  388.         local carry = proxy:read(sim.carry_node) and 1 or 0
  389.         ImGui.Text("Carry:")
  390.         ImGui.SameLine()
  391.         ImGui.Text(string.format("%d", carry))
  392.        
  393.     end
  394.    
  395.     ImGui.End()
  396. end
  397.  
  398. return sim
  399.  
Advertisement
Add Comment
Please, Sign In to add comment