profibus_phy_mod.v 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074
  1. // vim: ts=4 sw=4 noexpandtab
  2. /*
  3. * Profibus PHY
  4. *
  5. * Copyright (c) 2019 Michael Buesch <m@bues.ch>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along
  18. * with this program; if not, write to the Free Software Foundation, Inc.,
  19. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20. */
  21. `ifndef PROFIBUS_PHY_MOD_V_
  22. `define PROFIBUS_PHY_MOD_V_
  23. `include "uart_mod.v"
  24. `include "spi_slave_mod.v"
  25. `include "block_ram_mod.v"
  26. /* Host SPI message format:
  27. *
  28. * Data message master to slave:
  29. * Byte 0 1 2...
  30. * [0xAA] [FLG] [DATA] ...
  31. * | | |
  32. * | | |> from 1 up to 255 Profibus telegram bytes
  33. * | |> Flags
  34. * |> Start of message magic constant
  35. *
  36. * Data message slave to master:
  37. * Byte 0 1 2 ... 9 10
  38. * [0x55] [FLG] [DATA0] ... [DATA7] [LEN]
  39. * | | | |
  40. * | | | |> Number of DATA bytes
  41. * | | |> from 1 up to 8 Profibus telegram bytes
  42. * | |> Flags
  43. * |> Start of message magic constant
  44. *
  45. * Control message:
  46. * Byte 0 1 2 3 4 5 6 7
  47. * [MAGC] [FLG] [CTRL] [DATA0] [DATA1] [DATA2] [DATA3] [CRC]
  48. * | | | | | | | |
  49. * | | | | | | | |> CRC-8
  50. * | | | | | | |> Control data byte 3 (LSB)
  51. * | | | | | |> Control data byte 2
  52. * | | | | |> Control data byte 1
  53. * | | | |> Control data byte 0 (MSB)
  54. * | | |> Control identifier
  55. * | |> Flags
  56. * |> Start of message magic constant.
  57. * 0xAA if master to slave.
  58. * 0x55 if slave to master.
  59. *
  60. * FLG: bit 7: odd parity of FLG bits 0-6
  61. * FLG: bit 6: unused (set to 0)
  62. * FLG: bit 5: unused (set to 0)
  63. * FLG: bit 4: unused (set to 0)
  64. * FLG: bit 3: A reset occurred. Get STATUS to see details.
  65. * FLG: bit 2: New STATUS available
  66. * FLG: bit 1: Control message
  67. * FLG: bit 0: Start of telegram
  68. *
  69. * CRC polynomial: x^8 + x^2 + x^1 + 1
  70. *
  71. * Padding byte: 0x00
  72. */
  73. module profibus_telegram_length (
  74. input clk,
  75. input n_reset,
  76. input [7:0] in_byte,
  77. input new_byte,
  78. output reg length_valid,
  79. output reg [7:0] length,
  80. output reg error,
  81. );
  82. localparam STATE_START = 0;
  83. localparam STATE_LE = 1;
  84. localparam STATE_LER = 2;
  85. localparam SD1 = 8'h10;
  86. localparam SD2 = 8'h68;
  87. localparam SD3 = 8'hA2;
  88. localparam SD4 = 8'hDC;
  89. localparam SC = 8'hE5;
  90. reg [7:0] byte_le;
  91. reg [1:0] state;
  92. initial begin
  93. length_valid <= 0;
  94. length <= 0;
  95. error <= 0;
  96. byte_le <= 0;
  97. state <= STATE_START;
  98. end
  99. always @(posedge clk) begin
  100. if (n_reset) begin
  101. case (state)
  102. STATE_START: begin
  103. if (new_byte) begin
  104. if (in_byte == SD1) begin
  105. length <= 6;
  106. error <= 0;
  107. length_valid <= 1;
  108. end else if (in_byte == SD2) begin
  109. length <= 0;
  110. error <= 0;
  111. length_valid <= 0;
  112. state <= STATE_LE;
  113. end else if (in_byte == SD3) begin
  114. length <= 14;
  115. error <= 0;
  116. length_valid <= 1;
  117. end else if (in_byte == SD4) begin
  118. length <= 3;
  119. error <= 0;
  120. length_valid <= 1;
  121. end else if (in_byte == SC) begin
  122. length <= 1;
  123. error <= 0;
  124. length_valid <= 1;
  125. end else begin
  126. length <= 0;
  127. error <= 1;
  128. length_valid <= 0;
  129. end
  130. end
  131. end
  132. STATE_LE: begin
  133. if (new_byte) begin
  134. if (in_byte >= 4 && in_byte <= 249) begin
  135. byte_le <= in_byte;
  136. state <= STATE_LER;
  137. end else begin
  138. error <= 1;
  139. length_valid <= 0;
  140. state <= STATE_START;
  141. end
  142. end
  143. end
  144. STATE_LER: begin
  145. if (new_byte) begin
  146. if (in_byte == byte_le) begin
  147. length <= byte_le + 6;
  148. error <= 0;
  149. length_valid <= 1;
  150. state <= STATE_START;
  151. end else begin
  152. error <= 1;
  153. length_valid <= 0;
  154. state <= STATE_START;
  155. end
  156. end
  157. end
  158. default: begin
  159. length_valid <= 0;
  160. length <= 0;
  161. error <= 0;
  162. byte_le <= 0;
  163. state <= STATE_START;
  164. end
  165. endcase
  166. end else begin
  167. /* Reset */
  168. length_valid <= 0;
  169. length <= 0;
  170. error <= 0;
  171. byte_le <= 0;
  172. state <= STATE_START;
  173. end
  174. end
  175. endmodule
  176. module profibus_phy #(
  177. parameter SPI_CPOL = 0, /* SPI clock polarity. Can be 0 or 1. */
  178. parameter SPI_CPHA = 0, /* SPI clock phase. Can be 0 or 1. */
  179. parameter SPI_MSB_FIRST = 1, /* MSB transmit first enable. Can be 0 or 1. */
  180. ) (
  181. input clk, /* clock */
  182. input n_reset, /* Not reset */
  183. /* Host parallel interface: */
  184. output rx_irq_edge, /* Received data available (edge trigger) */
  185. output rx_irq_level, /* Received data available (level trigger) */
  186. /* Host SPI bus interface: */
  187. input mosi, /* SPI bus MOSI signal */
  188. output miso, /* SPI bus MISO signal */
  189. input sck, /* SPI bus clock signal */
  190. input ss, /* SPI bus slave select signal */
  191. /* Profibus RS485 bus: */
  192. input rx, /* Raw receive signal line */
  193. output rx_active, /* PB receive in progress (optional) */
  194. output rx_error, /* PB receive error (optional) */
  195. output tx, /* Raw transmit signal line */
  196. output tx_active, /* PB transmit in progress (optional) */
  197. output tx_error, /* PB transmit error (optional) */
  198. `ifdef DEBUG
  199. /* Debug interface: */
  200. output reg debug,
  201. `endif
  202. );
  203. `include "parity_func.v"
  204. `include "crc8_func.v"
  205. localparam TXBUF_ADDR_BITS = 8;
  206. localparam RXBUF_ADDR_BITS = 8;
  207. /* Start of SPI message magic constant. */
  208. localparam SPI_MS_MAGIC = 8'hAA; /* Master to slave */
  209. localparam SPI_SM_MAGIC = 8'h55; /* Slave to master */
  210. /* SPI message FLG bits */
  211. localparam SPI_FLG_START = 0;
  212. localparam SPI_FLG_CTRL = 1;
  213. localparam SPI_FLG_NEWSTAT = 2;
  214. localparam SPI_FLG_RESET = 3;
  215. localparam SPI_FLG_UNUSED4 = 4;
  216. localparam SPI_FLG_UNUSED5 = 5;
  217. localparam SPI_FLG_UNUSED6 = 6;
  218. localparam SPI_FLG_PARITY = 7;
  219. /* SPI control message IDs. */
  220. localparam SPICTRL_NOP = 0;
  221. localparam SPICTRL_PING = 1;
  222. localparam SPICTRL_PONG = 2;
  223. localparam SPICTRL_SOFTRESET = 3;
  224. localparam SPICTRL_GETSTATUS = 4;
  225. localparam SPICTRL_STATUS = 5;
  226. localparam SPICTRL_GETBAUD = 6;
  227. localparam SPICTRL_BAUD = 7;
  228. /* Status message data bits */
  229. localparam SPISTAT_PONRESET = 0;
  230. localparam SPISTAT_HARDRESET = 1;
  231. localparam SPISTAT_SOFTRESET = 2;
  232. localparam SPISTAT_TXOVR = 3;
  233. localparam SPISTAT_RXOVR = 4;
  234. localparam SPISTAT_CTRLCRCERR = 5;
  235. /***********************************************************/
  236. /* General part */
  237. /***********************************************************/
  238. /* Power-on-reset, hard-reset and soft-reset status. */
  239. reg n_poweronreset_status;
  240. reg n_hardreset_status;
  241. reg softreset_status;
  242. /* Soft-reset trigger. */
  243. reg softreset;
  244. wire any_reset_status;
  245. assign any_reset_status = ~n_poweronreset_status | ~n_hardreset_status | softreset_status;
  246. /* SPICTRL_STATUS should be fetched, if 1. */
  247. wire new_status_available;
  248. assign new_status_available = any_reset_status | tx_buf_overflow_get() |
  249. rx_buf_overflow_get() | spirx_ctrl_crcerr_get();
  250. initial begin
  251. n_poweronreset_status <= 0;
  252. n_hardreset_status <= 0;
  253. softreset_status <= 0;
  254. softreset <= 0;
  255. end
  256. /***********************************************************/
  257. /* Data buffer: Profibus transmit buffer */
  258. /***********************************************************/
  259. reg [TXBUF_ADDR_BITS - 1 : 0] tx_buf_wr_addr;
  260. wire [TXBUF_ADDR_BITS - 1 : 0] tx_buf_wr_addr_next;
  261. reg [7:0] tx_buf_wr_data;
  262. reg tx_buf_wr;
  263. reg [TXBUF_ADDR_BITS - 1 : 0] tx_buf_rd_addr;
  264. wire [7:0] tx_buf_rd_data;
  265. reg [1:0] tx_buf_overflow;
  266. block_ram #(
  267. .ADDR_WIDTH(TXBUF_ADDR_BITS),
  268. .DATA_WIDTH(8),
  269. .MEM_BYTES(1 << TXBUF_ADDR_BITS),
  270. ) tx_buf (
  271. .clk(clk),
  272. .addr0(tx_buf_wr_addr),
  273. .wr_data0(tx_buf_wr_data),
  274. .wr0(tx_buf_wr),
  275. .addr1(tx_buf_rd_addr),
  276. .rd_data1(tx_buf_rd_data),
  277. );
  278. assign tx_buf_wr_addr_next = tx_buf_wr_addr + 1;
  279. initial begin
  280. tx_buf_wr_addr <= 0;
  281. tx_buf_wr_data <= 0;
  282. tx_buf_wr <= 0;
  283. tx_buf_rd_addr <= 0;
  284. tx_buf_overflow <= 0;
  285. end
  286. function automatic tx_buf_overflow_get;
  287. begin tx_buf_overflow_get = tx_buf_overflow[0] ^ tx_buf_overflow[1]; end
  288. endfunction
  289. task automatic tx_buf_overflow_set;
  290. begin tx_buf_overflow[0] <= ~tx_buf_overflow[1]; end
  291. endtask
  292. task automatic tx_buf_overflow_reset;
  293. begin tx_buf_overflow[1] <= tx_buf_overflow[0]; end
  294. endtask
  295. /***********************************************************/
  296. /* Data buffer: Profibus receive buffer */
  297. /***********************************************************/
  298. localparam RXBUF_SOT_BIT = 8; /* Start-of-telegram marker bit. */
  299. reg [RXBUF_ADDR_BITS - 1 : 0] rx_buf_wr_addr;
  300. wire [RXBUF_ADDR_BITS - 1 : 0] rx_buf_wr_addr_next;
  301. reg [8:0] rx_buf_wr_data;
  302. reg rx_buf_wr;
  303. reg [RXBUF_ADDR_BITS - 1 : 0] rx_buf_rd_addr;
  304. wire [8:0] rx_buf_rd_data;
  305. reg [1:0] rx_buf_overflow;
  306. block_ram #(
  307. .ADDR_WIDTH(RXBUF_ADDR_BITS),
  308. .DATA_WIDTH(9),
  309. .MEM_BYTES(1 << RXBUF_ADDR_BITS),
  310. ) rx_buf (
  311. .clk(clk),
  312. .addr0(rx_buf_wr_addr),
  313. .wr_data0(rx_buf_wr_data),
  314. .wr0(rx_buf_wr),
  315. .addr1(rx_buf_rd_addr),
  316. .rd_data1(rx_buf_rd_data),
  317. );
  318. assign rx_buf_wr_addr_next = rx_buf_wr_addr + 1;
  319. initial begin
  320. rx_buf_wr_addr <= 0;
  321. rx_buf_wr_data <= 0;
  322. rx_buf_wr <= 0;
  323. rx_buf_rd_addr <= 0;
  324. rx_buf_overflow <= 0;
  325. end
  326. function automatic rx_buf_overflow_get;
  327. begin rx_buf_overflow_get = rx_buf_overflow[0] ^ rx_buf_overflow[1]; end
  328. endfunction
  329. task automatic rx_buf_overflow_set;
  330. begin rx_buf_overflow[0] <= ~rx_buf_overflow[1]; end
  331. endtask
  332. task automatic rx_buf_overflow_reset;
  333. begin rx_buf_overflow[1] <= rx_buf_overflow[0]; end
  334. endtask
  335. /***********************************************************/
  336. /* UART module */
  337. /***********************************************************/
  338. wire uart_rx_irq;
  339. wire [7:0] uart_rx_data;
  340. wire uart_rx_parity_ok;
  341. wire uart_rx_frame_error;
  342. wire uart_rx_active;
  343. wire uart_tx_irq;
  344. wire uart_tx_active;
  345. wire uart_tx_pending;
  346. reg [7:0] uart_tx_data;
  347. reg uart_tx_trigger;
  348. reg [23:0] uart_clks_per_sym;
  349. uart_half_duplex #(
  350. .DATABITS(8),
  351. .PARITY_EVEN(1),
  352. .STOP(1),
  353. .ACTIVE_LOW(0),
  354. ) uart (
  355. .clk(clk),
  356. .n_reset(n_reset),
  357. .clks_per_sym(uart_clks_per_sym),
  358. .rx(rx),
  359. .rx_irq(uart_rx_irq),
  360. .rx_active(uart_rx_active),
  361. .rx_data(uart_rx_data),
  362. .rx_parity_ok(uart_rx_parity_ok),
  363. .rx_frame_error(uart_rx_frame_error),
  364. .tx(tx),
  365. .tx_irq(uart_tx_irq),
  366. .tx_active(uart_tx_active),
  367. .tx_pending(uart_tx_pending),
  368. .tx_data(uart_tx_data),
  369. .tx_trigger(uart_tx_trigger),
  370. );
  371. assign rx_active = uart_rx_active;
  372. assign rx_error = ~uart_rx_parity_ok | uart_rx_frame_error;
  373. assign tx_active = uart_tx_active;
  374. assign tx_error = spirx_lencalc_error;
  375. initial begin
  376. uart_tx_data <= 0;
  377. uart_tx_trigger <= 0;
  378. uart_clks_per_sym <= 0;
  379. end
  380. /***********************************************************/
  381. /* SPI module */
  382. /***********************************************************/
  383. wire spi_rx_irq;
  384. wire spi_tx_irq;
  385. wire [7:0] spi_rx_data;
  386. reg [7:0] spi_tx_data;
  387. spi_slave #(
  388. .WORDSIZE(8),
  389. .CPOL(SPI_CPOL),
  390. .CPHA(SPI_CPHA),
  391. .MSB_FIRST(SPI_MSB_FIRST),
  392. ) spi (
  393. .clk(clk),
  394. .mosi(mosi),
  395. .miso(miso),
  396. .sck(sck),
  397. .ss(ss),
  398. .rx_irq(spi_rx_irq),
  399. .rx_data(spi_rx_data),
  400. .tx_data(spi_tx_data),
  401. );
  402. assign spi_tx_irq = spi_rx_irq;
  403. initial begin
  404. spi_tx_data <= 0;
  405. end
  406. /***********************************************************/
  407. /* UART receive */
  408. /* This process receives data from the Profibus line */
  409. /* and puts it into the Profibus receive buffer. */
  410. /***********************************************************/
  411. reg [23:0] tsyn_clks;
  412. /* Receive interrupts */
  413. assign rx_irq_edge = rx_buf_wr;
  414. assign rx_irq_level = rx_buf_wr | (rx_buf_wr_addr != rx_buf_rd_addr);
  415. initial begin
  416. tsyn_clks <= 0;
  417. end
  418. always @(posedge clk) begin
  419. if (n_reset & ~softreset) begin
  420. if (uart_rx_irq) begin
  421. if (uart_rx_parity_ok & ~uart_rx_frame_error) begin
  422. if (rx_buf_wr_addr_next != rx_buf_rd_addr) begin
  423. rx_buf_wr_data[7:0] <= uart_rx_data;
  424. /* Start-of-telegram bit. */
  425. rx_buf_wr_data[RXBUF_SOT_BIT] <= (timer_idle_saved >= tsyn_clks);
  426. rx_buf_wr <= 1;
  427. end else begin
  428. /* RX buffer overflow. */
  429. rx_buf_overflow_set();
  430. end
  431. end
  432. end else begin
  433. if (rx_buf_wr) begin
  434. rx_buf_wr <= 0;
  435. rx_buf_wr_addr <= rx_buf_wr_addr_next;
  436. end
  437. end
  438. end else begin
  439. /* Reset */
  440. rx_buf_wr <= 0;
  441. rx_buf_wr_addr <= 0;
  442. end
  443. end
  444. /***********************************************************/
  445. /* UART transmit. */
  446. /* This process transmits data to the Profibus line */
  447. /* from the Profibus transmit buffer. */
  448. /***********************************************************/
  449. always @(posedge clk) begin
  450. if (n_reset & ~softreset) begin
  451. if (uart_tx_trigger) begin
  452. uart_tx_trigger <= 0;
  453. end else begin
  454. /* Check if new TX data is pending. */
  455. if (tx_buf_rd_addr != tx_buf_wr_addr) begin
  456. /* Check if we are able to transmit. */
  457. if (~uart_tx_active & ~uart_tx_pending) begin
  458. /* Transmit the byte to the PB line. */
  459. uart_tx_data <= tx_buf_rd_data;
  460. uart_tx_trigger <= 1;
  461. tx_buf_rd_addr <= tx_buf_rd_addr + 1;
  462. end
  463. end
  464. end
  465. end else begin
  466. /* Reset */
  467. uart_tx_data <= 0;
  468. uart_tx_trigger <= 0;
  469. tx_buf_rd_addr <= 0;
  470. end
  471. end
  472. /***********************************************************/
  473. /* SPI receive. */
  474. /* This process receives data from the host SPI bus */
  475. /* and puts it into the Profibus transmit buffer. */
  476. /***********************************************************/
  477. localparam SPIRX_BEGIN = 0;
  478. localparam SPIRX_FLG = 1;
  479. localparam SPIRX_DATA = 2;
  480. localparam SPIRX_CTRL = 3;
  481. localparam SPIRX_CTRL_DATA = 4;
  482. localparam SPIRX_CRC = 5;
  483. localparam SPIRX_CTRL_EXEC = 6;
  484. reg [2:0] spirx_state;
  485. reg [7:0] spirx_len;
  486. reg spirx_len_valid;
  487. reg [7:0] spirx_bytecount;
  488. reg [7:0] spirx_ctrl;
  489. reg [31:0] spirx_ctrl_data;
  490. reg [7:0] spirx_crc;
  491. reg [1:0] spirx_ctrl_crcerr;
  492. /* Length calculation of PB frames. */
  493. wire spirx_lencalc_n_reset_wire;
  494. reg spirx_lencalc_n_reset;
  495. reg [7:0] spirx_lencalc_byte;
  496. reg spirx_lencalc_new;
  497. wire spirx_lencalc_valid;
  498. wire [7:0] spirx_lencalc_length;
  499. wire spirx_lencalc_error;
  500. profibus_telegram_length spirx_lencalc (
  501. .clk(clk),
  502. .n_reset(spirx_lencalc_n_reset_wire),
  503. .in_byte(spirx_lencalc_byte),
  504. .new_byte(spirx_lencalc_new),
  505. .length_valid(spirx_lencalc_valid),
  506. .length(spirx_lencalc_length),
  507. .error(spirx_lencalc_error),
  508. );
  509. assign spirx_lencalc_n_reset_wire = spirx_lencalc_n_reset & ~softreset & n_reset;
  510. initial begin
  511. spirx_state <= SPIRX_BEGIN;
  512. spirx_len <= 0;
  513. spirx_len_valid <= 0;
  514. spirx_bytecount <= 0;
  515. spirx_ctrl <= 0;
  516. spirx_ctrl_data <= 0;
  517. spirx_crc <= 0;
  518. spirx_ctrl_crcerr <= 0;
  519. spirx_lencalc_n_reset <= 0;
  520. spirx_lencalc_byte <= 0;
  521. spirx_lencalc_new <= 0;
  522. end
  523. function automatic spirx_ctrl_crcerr_get;
  524. begin spirx_ctrl_crcerr_get = spirx_ctrl_crcerr[0] ^ spirx_ctrl_crcerr[1]; end
  525. endfunction
  526. task automatic spirx_ctrl_crcerr_set;
  527. begin spirx_ctrl_crcerr[0] <= ~spirx_ctrl_crcerr[1]; end
  528. endtask
  529. task automatic spirx_ctrl_crcerr_reset;
  530. begin spirx_ctrl_crcerr[1] <= spirx_ctrl_crcerr[0]; end
  531. endtask
  532. always @(posedge clk) begin
  533. if (n_reset & ~softreset) begin
  534. case (spirx_state)
  535. SPIRX_BEGIN: begin
  536. /* Wait for start of SPI receive. */
  537. if (spi_rx_irq) begin
  538. if (spi_rx_data == SPI_MS_MAGIC) begin
  539. spirx_ctrl <= 0;
  540. spirx_ctrl_data <= 0;
  541. spirx_len <= 0;
  542. spirx_len_valid <= 0;
  543. spirx_crc <= 8'hFF;
  544. spirx_state <= SPIRX_FLG;
  545. end
  546. end
  547. if (tx_buf_wr) begin
  548. tx_buf_wr_addr <= tx_buf_wr_addr + 1;
  549. tx_buf_wr <= 0;
  550. end
  551. spirx_lencalc_byte <= 0;
  552. spirx_lencalc_new <= 0;
  553. spirx_lencalc_n_reset <= 0;
  554. end
  555. SPIRX_FLG: begin
  556. /* Flags field. */
  557. if (spi_rx_irq) begin
  558. /* Check the FLG checksum. */
  559. if (parity8(ODD,
  560. spi_rx_data[0],
  561. spi_rx_data[1],
  562. spi_rx_data[2],
  563. spi_rx_data[3],
  564. spi_rx_data[4],
  565. spi_rx_data[5],
  566. spi_rx_data[6],
  567. spi_rx_data[7]) == 0) begin
  568. if (spi_rx_data[SPI_FLG_CTRL]) begin
  569. /* We have a control message. */
  570. spirx_bytecount <= 0;
  571. spirx_state <= SPIRX_CTRL;
  572. end else begin
  573. /* Begin PB data. */
  574. spirx_lencalc_n_reset <= 1;
  575. spirx_bytecount <= 0;
  576. spirx_state <= SPIRX_DATA;
  577. end
  578. end else begin
  579. /* Incorrect checksum. */
  580. spirx_state <= SPIRX_BEGIN;
  581. end
  582. end
  583. end
  584. SPIRX_DATA: begin
  585. /* Receive data bytes. */
  586. if (spirx_len_valid) begin
  587. /* spirx_len is valid.
  588. * Check if we received all bytes. */
  589. if (spirx_bytecount >= spirx_len) begin
  590. spirx_state <= SPIRX_BEGIN;
  591. end
  592. end else begin
  593. /* Try to calculate the telegram length. */
  594. spirx_lencalc_byte <= spi_rx_data;
  595. spirx_lencalc_new <= spi_rx_irq;
  596. if (spirx_lencalc_error) begin
  597. /* Failed to calculate the length. Abort. */
  598. spirx_lencalc_n_reset <= 0;
  599. spirx_state <= SPIRX_BEGIN;
  600. end else if (spirx_lencalc_valid) begin
  601. /* Successfully calculated the data length. */
  602. spirx_len <= spirx_lencalc_length;
  603. spirx_len_valid <= 1;
  604. spirx_lencalc_n_reset <= 0;
  605. end
  606. end
  607. if (tx_buf_wr) begin
  608. /* Increment TX buffer pointer. */
  609. tx_buf_wr_addr <= tx_buf_wr_addr + 1;
  610. tx_buf_wr <= 0;
  611. end else begin
  612. /* Did we receive a byte? */
  613. if (spi_rx_irq) begin
  614. if (tx_buf_wr_addr_next != tx_buf_rd_addr) begin
  615. /* Put the new byte into the TX buffer. */
  616. tx_buf_wr_data <= spi_rx_data;
  617. tx_buf_wr <= 1;
  618. spirx_bytecount <= spirx_bytecount + 1;
  619. end else begin
  620. /* TX buffer overflow. */
  621. tx_buf_overflow_set();
  622. spirx_bytecount <= spirx_bytecount + 1;
  623. end
  624. end
  625. end
  626. end
  627. SPIRX_CTRL: begin
  628. /* Receive control command byte. */
  629. if (spi_rx_irq) begin
  630. spirx_ctrl <= spi_rx_data;
  631. spirx_crc <= crc8(spirx_crc, spi_rx_data);
  632. spirx_state <= SPIRX_CTRL_DATA;
  633. end
  634. end
  635. SPIRX_CTRL_DATA: begin
  636. /* Receive control data bytes. */
  637. if (spi_rx_irq) begin
  638. spirx_ctrl_data <= (spirx_ctrl_data << 8) | spi_rx_data;
  639. spirx_crc <= crc8(spirx_crc, spi_rx_data);
  640. if (spirx_bytecount >= 4 - 1) begin
  641. spirx_state <= SPIRX_CRC;
  642. end
  643. spirx_bytecount <= spirx_bytecount + 1;
  644. end
  645. end
  646. SPIRX_CRC: begin
  647. /* Receive CRC byte. */
  648. if (spi_rx_irq) begin
  649. if (spi_rx_data == spirx_crc) begin
  650. spirx_state <= SPIRX_CTRL_EXEC;
  651. end else begin
  652. /* Incorrect CRC. Do not run the control command. */
  653. spirx_ctrl_crcerr_set();
  654. spirx_state <= SPIRX_BEGIN;
  655. end
  656. end
  657. end
  658. SPIRX_CTRL_EXEC: begin
  659. /* Handle received control message. */
  660. case (spirx_ctrl)
  661. SPICTRL_NOP: begin
  662. /* NOP command. Do nothing. */
  663. spirx_state <= SPIRX_BEGIN;
  664. end
  665. SPICTRL_PING: begin
  666. /* PING command. Send PONG. */
  667. if (spitx_ctrl_pending == spitx_ctrl_pending_ack) begin
  668. spitx_ctrl_reply <= SPICTRL_PONG;
  669. spitx_ctrl_reply_data <= 0;
  670. spitx_ctrl_pending <= ~spitx_ctrl_pending_ack;
  671. spirx_state <= SPIRX_BEGIN;
  672. end
  673. end
  674. SPICTRL_PONG: begin
  675. /* Ignore. */
  676. spirx_state <= SPIRX_BEGIN;
  677. end
  678. SPICTRL_SOFTRESET: begin
  679. /* Trigger a soft reset. */
  680. softreset <= 1;
  681. spirx_state <= SPIRX_BEGIN;
  682. end
  683. SPICTRL_GETSTATUS: begin
  684. if (spitx_ctrl_pending == spitx_ctrl_pending_ack) begin
  685. spitx_ctrl_reply <= SPICTRL_STATUS;
  686. spitx_ctrl_reply_data[SPISTAT_PONRESET] <= ~n_poweronreset_status;
  687. spitx_ctrl_reply_data[SPISTAT_HARDRESET] <= ~n_hardreset_status;
  688. spitx_ctrl_reply_data[SPISTAT_SOFTRESET] <= softreset_status;
  689. spitx_ctrl_reply_data[SPISTAT_TXOVR] <= tx_buf_overflow_get();
  690. spitx_ctrl_reply_data[SPISTAT_RXOVR] <= rx_buf_overflow_get();
  691. spitx_ctrl_reply_data[SPISTAT_CTRLCRCERR] <= spirx_ctrl_crcerr_get();
  692. spitx_ctrl_reply_data[31:6] <= 0;
  693. spitx_ctrl_pending <= ~spitx_ctrl_pending_ack;
  694. /* Reset all error states. */
  695. tx_buf_overflow_reset();
  696. rx_buf_overflow_reset();
  697. spirx_ctrl_crcerr_reset();
  698. /* Reset all reset status bits */
  699. n_poweronreset_status <= 1;
  700. n_hardreset_status <= 1;
  701. softreset_status <= 0;
  702. spirx_state <= SPIRX_BEGIN;
  703. end
  704. end
  705. SPICTRL_STATUS: begin
  706. /* Ignore. */
  707. spirx_state <= SPIRX_BEGIN;
  708. end
  709. SPICTRL_GETBAUD: begin
  710. if (spitx_ctrl_pending == spitx_ctrl_pending_ack) begin
  711. spitx_ctrl_reply <= SPICTRL_BAUD;
  712. spitx_ctrl_reply_data[31:24] <= 0;
  713. spitx_ctrl_reply_data[23:0] <= spirx_ctrl_data[23:0];
  714. spitx_ctrl_pending <= ~spitx_ctrl_pending_ack;
  715. spirx_state <= SPIRX_BEGIN;
  716. end
  717. end
  718. SPICTRL_BAUD: begin
  719. if (spitx_ctrl_pending == spitx_ctrl_pending_ack) begin
  720. spitx_ctrl_reply <= SPICTRL_BAUD;
  721. spitx_ctrl_reply_data[31:24] <= 0;
  722. spitx_ctrl_reply_data[23:0] <= spirx_ctrl_data[23:0];
  723. spitx_ctrl_pending <= ~spitx_ctrl_pending_ack;
  724. /* Set the new baud rate. */
  725. uart_clks_per_sym[23:0] <= spirx_ctrl_data[23:0];
  726. /* Set the new TSYN timing.
  727. * The number of TSYN clks is:
  728. * clks_per_symbol * 33
  729. */
  730. tsyn_clks <= (spirx_ctrl_data[23:0] << 5) + spirx_ctrl_data[23:0];
  731. spirx_state <= SPIRX_BEGIN;
  732. end
  733. end
  734. default: begin
  735. /* Unknown control command. */
  736. spirx_state <= SPIRX_BEGIN;
  737. end
  738. endcase
  739. end
  740. default: begin
  741. /* Invalid case. */
  742. spirx_ctrl <= 0;
  743. spirx_ctrl_data <= 0;
  744. tx_buf_wr_addr <= 0;
  745. tx_buf_wr_data <= 0;
  746. tx_buf_wr <= 0;
  747. spirx_state <= SPIRX_BEGIN;
  748. spirx_lencalc_n_reset <= 0;
  749. end
  750. endcase
  751. end else begin
  752. /* Reset */
  753. spirx_ctrl <= 0;
  754. spirx_ctrl_data <= 0;
  755. tx_buf_wr_addr <= 0;
  756. tx_buf_wr_data <= 0;
  757. tx_buf_wr <= 0;
  758. spirx_state <= SPIRX_BEGIN;
  759. spirx_lencalc_n_reset <= 0;
  760. rx_buf_overflow_reset();
  761. tx_buf_overflow_reset();
  762. spirx_ctrl_crcerr_reset();
  763. softreset_status <= softreset;
  764. n_hardreset_status <= n_reset;
  765. n_poweronreset_status <= 1;
  766. softreset <= 0;
  767. end
  768. end
  769. /***********************************************************/
  770. /* SPI transmit. */
  771. /* This process transmits data to the host SPI bus */
  772. /* from the Profibus receive buffer. */
  773. /***********************************************************/
  774. reg [7:0] spitx_ctrl_reply;
  775. reg [31:0] spitx_ctrl_reply_data;
  776. reg spitx_ctrl_pending;
  777. reg spitx_ctrl_pending_ack;
  778. reg [7:0] spitx_bytecount;
  779. reg [7:0] spitx_len;
  780. reg spitx_tail;
  781. reg spitx_ctrl_running;
  782. reg spitx_data_running;
  783. reg [7:0] spitx_crc;
  784. initial begin
  785. spitx_ctrl_reply <= 0;
  786. spitx_ctrl_reply_data <= 0;
  787. spitx_ctrl_pending <= 0;
  788. spitx_ctrl_pending_ack <= 0;
  789. spitx_bytecount <= 0;
  790. spitx_len <= 0;
  791. spitx_ctrl_running <= 0;
  792. spitx_data_running <= 0;
  793. spitx_crc <= 0;
  794. end
  795. always @(posedge clk) begin
  796. if (n_reset & ~softreset) begin
  797. /* Are we currently not transmitting a data frame
  798. * and is a control frame pending? */
  799. if (~spitx_data_running &&
  800. spitx_ctrl_pending != spitx_ctrl_pending_ack) begin
  801. if (spi_tx_irq) begin
  802. case (spitx_bytecount)
  803. 0: begin
  804. spi_tx_data <= SPI_SM_MAGIC;
  805. spitx_bytecount <= spitx_bytecount + 1;
  806. spitx_ctrl_running <= 1;
  807. end
  808. 1: begin
  809. spi_tx_data[SPI_FLG_START] <= 0;
  810. spi_tx_data[SPI_FLG_CTRL] <= 1;
  811. spi_tx_data[SPI_FLG_NEWSTAT] <= new_status_available;
  812. spi_tx_data[SPI_FLG_RESET] <= any_reset_status;
  813. spi_tx_data[SPI_FLG_UNUSED4] <= 0;
  814. spi_tx_data[SPI_FLG_UNUSED5] <= 0;
  815. spi_tx_data[SPI_FLG_UNUSED6] <= 0;
  816. spi_tx_data[SPI_FLG_PARITY] <= parity8(ODD, 0,
  817. 0,
  818. 1,
  819. new_status_available,
  820. any_reset_status,
  821. 0,
  822. 0,
  823. 0);
  824. spitx_crc <= 8'hFF;
  825. spitx_bytecount <= spitx_bytecount + 1;
  826. spitx_ctrl_running <= 1;
  827. end
  828. 2: begin
  829. spi_tx_data <= spitx_ctrl_reply;
  830. spitx_crc <= crc8(spitx_crc, spitx_ctrl_reply);
  831. spitx_bytecount <= spitx_bytecount + 1;
  832. spitx_ctrl_running <= 1;
  833. end
  834. 3: begin
  835. spi_tx_data <= spitx_ctrl_reply_data[31:24];
  836. spitx_crc <= crc8(spitx_crc, spitx_ctrl_reply_data[31:24]);
  837. spitx_bytecount <= spitx_bytecount + 1;
  838. spitx_ctrl_running <= 1;
  839. end
  840. 4: begin
  841. spi_tx_data <= spitx_ctrl_reply_data[23:16];
  842. spitx_crc <= crc8(spitx_crc, spitx_ctrl_reply_data[23:16]);
  843. spitx_bytecount <= spitx_bytecount + 1;
  844. spitx_ctrl_running <= 1;
  845. end
  846. 5: begin
  847. spi_tx_data <= spitx_ctrl_reply_data[15:8];
  848. spitx_crc <= crc8(spitx_crc, spitx_ctrl_reply_data[15:8]);
  849. spitx_bytecount <= spitx_bytecount + 1;
  850. spitx_ctrl_running <= 1;
  851. end
  852. 6: begin
  853. spi_tx_data <= spitx_ctrl_reply_data[7:0];
  854. spitx_crc <= crc8(spitx_crc, spitx_ctrl_reply_data[7:0]);
  855. spitx_bytecount <= spitx_bytecount + 1;
  856. spitx_ctrl_running <= 1;
  857. end
  858. 7: begin
  859. spi_tx_data <= spitx_crc;
  860. spitx_bytecount <= 0;
  861. spitx_ctrl_running <= 0;
  862. spitx_ctrl_pending_ack <= spitx_ctrl_pending;
  863. end
  864. default: begin
  865. spitx_bytecount <= 0;
  866. spitx_ctrl_running <= 0;
  867. spitx_ctrl_pending_ack <= spitx_ctrl_pending;
  868. end
  869. endcase
  870. end
  871. /* Are we currently not transmitting a control frame
  872. * and is a data frame pending? */
  873. end else if ((~spitx_ctrl_running &&
  874. rx_buf_wr_addr != rx_buf_rd_addr) ||
  875. spitx_data_running) begin
  876. if (spi_tx_irq) begin
  877. /* We have a new PB telegram byte. Send it to the host. */
  878. if (spitx_bytecount == 0) begin
  879. spi_tx_data <= SPI_SM_MAGIC;
  880. spitx_bytecount <= spitx_bytecount + 1;
  881. spitx_len <= 0;
  882. spitx_tail <= 0;
  883. spitx_data_running <= 1;
  884. end else if (spitx_bytecount == 1) begin
  885. spi_tx_data[SPI_FLG_START] = rx_buf_rd_data[RXBUF_SOT_BIT];
  886. spi_tx_data[SPI_FLG_CTRL] = 0;
  887. spi_tx_data[SPI_FLG_NEWSTAT] = new_status_available;
  888. spi_tx_data[SPI_FLG_RESET] = any_reset_status;
  889. spi_tx_data[SPI_FLG_UNUSED4] = 0;
  890. spi_tx_data[SPI_FLG_UNUSED5] = 0;
  891. spi_tx_data[SPI_FLG_UNUSED6] = 0;
  892. spi_tx_data[SPI_FLG_PARITY] = parity8(ODD, 0,
  893. rx_buf_rd_data[RXBUF_SOT_BIT],
  894. 0,
  895. new_status_available,
  896. any_reset_status,
  897. 0,
  898. 0,
  899. 0);
  900. spitx_bytecount <= spitx_bytecount + 1;
  901. spitx_data_running <= 1;
  902. end else if (spitx_bytecount >= 2 && spitx_bytecount <= 9) begin
  903. if (spitx_tail ||
  904. (rx_buf_wr_addr == rx_buf_rd_addr) ||
  905. (spitx_bytecount >= 3 && rx_buf_rd_data[RXBUF_SOT_BIT])) begin
  906. spi_tx_data <= 0;
  907. spitx_bytecount <= spitx_bytecount + 1;
  908. spitx_tail <= 1;
  909. end else begin
  910. spi_tx_data <= rx_buf_rd_data;
  911. rx_buf_rd_addr <= rx_buf_rd_addr + 1;
  912. spitx_bytecount <= spitx_bytecount + 1;
  913. spitx_len <= spitx_len + 1;
  914. end
  915. spitx_data_running <= 1;
  916. end else begin
  917. spi_tx_data <= spitx_len;
  918. spitx_bytecount <= 0;
  919. spitx_data_running <= 0;
  920. end
  921. end
  922. end else begin
  923. /* No frame pending. */
  924. if (spi_tx_irq) begin
  925. spi_tx_data <= 0;
  926. end
  927. spitx_bytecount <= 0;
  928. spitx_data_running <= 0;
  929. spitx_ctrl_running <= 0;
  930. end
  931. end else begin
  932. /* Reset. */
  933. spi_tx_data <= 0;
  934. spitx_bytecount <= 0;
  935. spitx_len <= 0;
  936. spitx_tail <= 0;
  937. spitx_ctrl_running <= 0;
  938. spitx_data_running <= 0;
  939. spitx_ctrl_pending_ack <= spitx_ctrl_pending;
  940. spitx_crc <= 0;
  941. end
  942. end
  943. /***********************************************************/
  944. /* PB timekeeping. */
  945. /***********************************************************/
  946. reg timer_idle_active;
  947. reg [23:0] timer_idle;
  948. reg [23:0] timer_idle_saved;
  949. localparam TIMER_MAX = 24'hFFFFFF;
  950. initial begin
  951. timer_idle_active <= 0;
  952. timer_idle <= 0;
  953. timer_idle_saved <= TIMER_MAX;
  954. end
  955. always @(posedge clk) begin
  956. if (n_reset & ~softreset) begin
  957. if (uart_tx_active | uart_tx_irq |
  958. uart_rx_active | uart_rx_irq) begin
  959. /* A PB transmission is active. Reset idle timer. */
  960. if (timer_idle_active) begin
  961. timer_idle_saved <= timer_idle;
  962. end
  963. timer_idle_active <= 0;
  964. timer_idle <= 0;
  965. end else begin
  966. /* PB is idle, increment the idle timer. Avoid overflow. */
  967. if (timer_idle < TIMER_MAX) begin
  968. timer_idle <= timer_idle + 1;
  969. end
  970. timer_idle_active <= 1;
  971. end
  972. end else begin
  973. timer_idle_active <= 0;
  974. timer_idle <= 0;
  975. timer_idle_saved <= TIMER_MAX;
  976. end
  977. end
  978. endmodule
  979. `endif /* PROFIBUS_PHY_MOD_V_ */