Advertisement
Guest User

Untitled

a guest
Apr 19th, 2021
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.83 KB | None | 0 0
  1. #
  2. # This file is part of LiteX.
  3. #
  4. # Copyright (c) 2021 Romain Dolbeau <[email protected]>
  5.  
  6. #module ps2_host(
  7. # input wire sys_clk,
  8. # input wire sys_rst,
  9. # inout wire ps2_clk,
  10. # inout wire ps2_data,
  11. #
  12. # input wire [7:0] tx_data,
  13. # input wire send_req,
  14. # output wire busy,
  15. #
  16. # output wire [7:0] rx_data,
  17. # output wire ready,
  18. # output wire error
  19. #);
  20. #module ps2interface(
  21. # clk,
  22. # rst,
  23. # ps2_clk,
  24. # ps2_data,
  25. # tx_data,
  26. # write,
  27. # rx_data,
  28. # read,
  29. # busy,
  30. # err
  31. #);
  32. # input clk;
  33. # input rst;
  34. # inout ps2_clk;
  35. # inout ps2_data;
  36. # input [7:0] tx_data;
  37. # input write;
  38. # output [7:0] rx_data;
  39. # output read;
  40. # output busy;
  41. # output err;
  42.  
  43. import os
  44. #from os import path
  45.  
  46. from migen import *
  47. from migen.genlib.fifo import SyncFIFOBuffered
  48.  
  49. from litex.soc.interconnect.csr import *
  50. from litex.soc.interconnect.csr_eventmanager import *
  51.  
  52. def _to_signal(obj):
  53. return obj.raw_bits() if isinstance(obj, Record) else obj
  54.  
  55. class PS2HostWrapper(Module, AutoCSR):
  56. def __init__(self, platform, pads, sys_clk_freq = 100e6, digilent=False):
  57. self.platform = platform
  58. if (not digilent):
  59. self.module_name = "ps2_host"
  60. else:
  61. self.module_name = "ps2interface"
  62. #pads = _to_signal(pads)
  63. tx_data_i = Signal(8)
  64. send_req_i = Signal()
  65. busy_o = Signal()
  66. rx_data_o = Signal(8)
  67. ready_o = Signal()
  68. error_o = Signal()
  69. # is there a way to pass 'define SYS_CLOCK_HZ $sys_clk_freq' to Verilog?
  70. # default 100e6 so fine
  71. # data -> 0-7: data; 31: valid
  72. self.rx_data = CSRStorage(size = 32, reset = 0, write_from_dev=True)
  73. # data -> 0-7: data; 31: valid
  74. self.tx_data = CSRStorage(size = 32, reset = 0, write_from_dev=True)
  75. # ctrl -> 0: interrupt enable, 1: reset, 31 -> interrupt
  76. self.ctrl = CSRStorage(size = 32, reset = 0, write_from_dev=True)
  77. in_ctrl_1_n_d = Signal()
  78. self.comb += in_ctrl_1_n_d.eq(~self.ctrl.storage[1:2])
  79. if (not digilent):
  80. self.module_params = dict(
  81. i_sys_clk = ClockSignal("sys"),
  82. i_sys_rst = in_ctrl_1_n_d,
  83. io_ps2_clk = pads.ps2_clk,
  84. io_ps2_data = pads.ps2_data,
  85. i_tx_data = tx_data_i,
  86. i_send_req = send_req_i,
  87. o_busy = busy_o,
  88. o_rx_data = rx_data_o,
  89. o_ready = ready_o,
  90. o_error = error_o
  91. )
  92. else:
  93. self.module_params = dict(
  94. i_clk = ClockSignal("sys"),
  95. i_rst = in_ctrl_1_n_d,
  96. io_ps2_clk = pads.ps2_clk,
  97. io_ps2_data = pads.ps2_data,
  98. i_tx_data = tx_data_i,
  99. i_write = send_req_i,
  100. o_rx_data = rx_data_o,
  101. o_read = ready_o,
  102. o_busy = busy_o,
  103. o_err = error_o
  104. )
  105.  
  106. self.submodules.rx_fifo = rx_fifo = SyncFIFOBuffered(width=8, depth=32) ## no fill control
  107. self.comb += rx_fifo.din.eq(rx_data_o)
  108. self.comb += rx_fifo.we.eq(ready_o)
  109. self.submodules.fsm = fsm = FSM(reset_state="IDLE")
  110. fsm.act("IDLE",
  111. self.rx_data.we.eq(0),
  112. self.tx_data.we.eq(0),
  113. self.ctrl.we.eq(0),
  114. rx_fifo.re.eq(0),
  115. send_req_i.eq(0),
  116. NextState("RESETKBD"))
  117. fsm.act("RESETKBD",
  118. self.rx_data.dat_w.eq(0xDEADBEEF), # recognizable value
  119. self.rx_data.we.eq(1),
  120. self.ctrl.dat_w.eq(0x00000002), # stop reset to verilog block
  121. self.ctrl.we.eq(1),
  122. tx_data_i.eq(0xFF), # send reset to KBD
  123. send_req_i.eq(1),
  124. NextState("RUN"))
  125. fsm.act("RUN",
  126. self.rx_data.we.eq(0),
  127. self.tx_data.we.eq(0),
  128. self.ctrl.we.eq(0),
  129. rx_fifo.re.eq(0),
  130. send_req_i.eq(0),
  131. If(rx_fifo.readable & ~self.ctrl.storage[31:32],
  132. self.rx_data.dat_w.eq(0x80000000 | rx_fifo.dout),
  133. self.rx_data.we.eq(1),
  134. self.ctrl.dat_w.eq(0x80000003), # must keep irq & !reset
  135. self.ctrl.we.eq(1),
  136. rx_fifo.re.eq(1)),
  137. If(~rx_fifo.readable & ~self.ctrl.storage[31:32],
  138. self.rx_data.dat_w.eq(0),
  139. self.rx_data.we.eq(1)
  140. ),
  141. If(self.tx_data.storage[31:32] & ~busy_o,
  142. tx_data_i.eq(self.tx_data.storage[0:8]),
  143. send_req_i.eq(1),
  144. self.tx_data.dat_w.eq(0),
  145. self.tx_data.we.eq(1)))
  146. ## irq
  147. self.submodules.ev = EventManager()
  148. in_ctrl_31_d = Signal()
  149. in_ctrl_0_d = Signal()
  150. self.comb += in_ctrl_31_d.eq(self.ctrl.storage[31:32])
  151. self.comb += in_ctrl_0_d.eq(self.ctrl.storage[0:1])
  152. #self.ev.keyev = EventSourceProcess(description="Key Event", edge="rising")
  153. self.ev.keyev = EventSourceLevel(description="Key Event")
  154. self.ev.finalize()
  155. self.comb += self.ev.keyev.trigger.eq(in_ctrl_31_d & in_ctrl_0_d)
  156. # instantiate verilog module
  157. self.specials += Instance(self.module_name, **self.module_params)
  158. # Add verilog sources
  159. self.add_sources(platform = self.platform, digilent = digilent)
  160.  
  161. def add_sources(self, platform, digilent):
  162. if (not digilent):
  163. platform.add_source(os.path.join("/home/dolbeau/ps2_host_controller/trunk/hdl/ps2_host_clk_ctrl.v"), "verilog")
  164. platform.add_source(os.path.join("/home/dolbeau/ps2_host_controller/trunk/hdl/ps2_host_defines.v"), "verilog")
  165. platform.add_source(os.path.join("/home/dolbeau/ps2_host_controller/trunk/hdl/ps2_host_rx.v"), "verilog")
  166. #platform.add_source(os.path.join("/home/dolbeau/ps2_host_controller/trunk/hdl/ps2_host_testbench.v"), "verilog")
  167. platform.add_source(os.path.join("/home/dolbeau/ps2_host_controller/trunk/hdl/ps2_host_tx.v"), "verilog")
  168. platform.add_source(os.path.join("/home/dolbeau/ps2_host_controller/trunk/hdl/ps2_host.v"), "verilog")
  169. platform.add_source(os.path.join("/home/dolbeau/ps2_host_controller/trunk/hdl/ps2_host_watchdog.v"), "verilog")
  170. #platform.add_source(os.path.join("/home/dolbeau/ps2_host_controller/trunk/hdl/timescale.v"), "verilog")
  171. else:
  172. platform.add_source(os.path.join("/home/dolbeau/PmodPS2_Demo/ps2interface.v"), "verilog")
  173.  
  174. # def do_finalize(self):
  175. # self.specials += Instance(self.module_name, **self.module_params)
  176. # self.add_sources(self.platform)
  177.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement