upsilon/firmware/rtl/spi/spi_switch.v

52 lines
1.1 KiB
Coq
Raw Normal View History

2023-03-03 03:06:50 -05:00
/* This module is a co-operative crossbar for the wires only. Each end
* implements its own SPI master.
*
* This crossbar is entirely controlled by the kernel.
*/
2023-03-08 23:17:41 -05:00
module spi_switch #(
2023-03-14 00:06:42 -04:00
parameter PORTS = 3
) (
2023-03-14 11:42:41 -04:00
/* verilator lint_off UNUSEDSIGNAL */
2023-03-14 00:06:42 -04:00
input [PORTS-1:0] select,
2023-03-14 11:42:41 -04:00
/* verilator lint_on UNUSEDSIGNAL */
2023-03-03 03:06:50 -05:00
2023-03-14 00:06:42 -04:00
output reg mosi,
2023-03-03 03:06:50 -05:00
input miso,
2023-03-14 00:06:42 -04:00
output reg sck,
output reg ss_L,
2023-03-03 03:06:50 -05:00
2023-03-08 23:17:41 -05:00
input [PORTS-1:0] mosi_ports,
2023-03-14 00:06:42 -04:00
output reg [PORTS-1:0] miso_ports,
2023-03-08 23:17:41 -05:00
input [PORTS-1:0] sck_ports,
input [PORTS-1:0] ss_L_ports
2023-03-03 03:06:50 -05:00
);
/* Avoid using for loops, they might not synthesize correctly.
Do things the old, dumb way instead.
*/
2023-03-14 11:42:41 -04:00
`define do_select(n) \
mosi = mosi_ports[n]; \
miso_ports = {{(PORTS-1){1'b0}},miso} << n; \
sck = sck_ports[n]; \
2023-03-08 23:17:41 -05:00
ss_L = ss_L_ports[n]
`define check_select(n) \
if (select[n]) begin \
2023-03-14 00:06:42 -04:00
`do_select(n); \
2023-03-03 03:06:50 -05:00
end
2023-03-14 00:06:42 -04:00
generate if (PORTS == 3) always @(*) begin
`check_select(2)
else `check_select(1)
2023-03-14 11:42:41 -04:00
else begin
`do_select(0);
end
2023-03-08 23:17:41 -05:00
end else always @(*) begin
2023-03-14 00:06:42 -04:00
`check_select(1)
else `do_select(0);
2023-03-08 23:17:41 -05:00
end endgenerate
2023-03-03 03:06:50 -05:00
endmodule
`undefineall