finished the hub's logic, half done with the interfaces, and hopefully working on pi logic soon
This commit is contained in:
@ -1,23 +1,25 @@
|
||||
// NOTE: The first byte is used for syncing due to using different clock domains
|
||||
`define SYNC_2FF
|
||||
`include <params.svh>
|
||||
module spi_interface(
|
||||
input logic rst,
|
||||
input logic sys_clk,
|
||||
input logic mosi,
|
||||
input logic cs,
|
||||
input logic sclk,
|
||||
input logic rx_ready,
|
||||
input logic tx_valid,
|
||||
input logic [7:0] tx_byte,
|
||||
input logic [1:0] tx_src,
|
||||
input logic [1:0] packet_size,
|
||||
output logic miso,
|
||||
output logic tx_ready,
|
||||
output logic rx_valid,
|
||||
output logic [7:0] rx_byte,
|
||||
output logic [7:0] rx_dest,
|
||||
output logic [7:0] rx_cmd,
|
||||
output logic rx_cmd_valid);
|
||||
input logic rst,
|
||||
input logic sys_clk,
|
||||
input logic mosi,
|
||||
input logic cs,
|
||||
input logic sclk,
|
||||
output logic miso,
|
||||
output logic [7:0] rx_byte,
|
||||
output logic rx_valid,
|
||||
input logic rx_ready,
|
||||
output logic [PACKET_ADDR_LEN - 1:0] rx_pkt_addr,
|
||||
input logic [7:0] tx_byte,
|
||||
input logic tx_valid,
|
||||
output logic tx_ready,
|
||||
output logic [PACKET_ADDR_LEN - 1:0] tx_pkt_addr,
|
||||
output logic [QUEUE_ADDR_LEN - 1:0] tx_queue_addr,
|
||||
input logic [QUEUE_ADDR_LEN - 1:0] tx_new_queue,
|
||||
input logic tx_new_queue_valid,
|
||||
output logic tx_new_queue_ready,
|
||||
input logic free_queue_empty);
|
||||
|
||||
timeunit 1ns;
|
||||
timeprecision 1ps;
|
||||
@ -28,11 +30,11 @@ module spi_interface(
|
||||
|
||||
async_get_clk_edges sync (.rst(rst),
|
||||
.ext_clk(sclk),
|
||||
.sys_clk(sys_clk),
|
||||
.clk_rising_edge(sclk_rising_edge),
|
||||
.clk_falling_edge(sclk_falling_edge));
|
||||
.sys_clk(sys_clk),
|
||||
.clk_rising_edge(sclk_rising_edge),
|
||||
.clk_falling_edge(sclk_falling_edge));
|
||||
|
||||
int bit_cnt = 0;
|
||||
shortint bit_cnt = 0;
|
||||
logic [7:0] rx_shift;
|
||||
logic [7:0] tx_shift = 8'b00101010;
|
||||
logic [7:0] rx_buff = '0;
|
||||
@ -40,48 +42,72 @@ module spi_interface(
|
||||
|
||||
always_ff @ (posedge sclk_rising_edge or posedge rst) begin
|
||||
if (rst) begin
|
||||
rx_shift <= '0;
|
||||
rx_buff <= '0;
|
||||
bit_cnt <= '0;
|
||||
rx_shift <= '0;
|
||||
rx_buff <= '0;
|
||||
bit_cnt <= '0;
|
||||
byte_ready <= 0;
|
||||
end
|
||||
else begin
|
||||
if (cs) begin
|
||||
rx_shift <= 0;
|
||||
rx_buff <= 0;
|
||||
bit_cnt <= 0;
|
||||
end else begin
|
||||
rx_shift <= {rx_shift[6:0], mosi};
|
||||
bit_cnt <= bit_cnt + 1;
|
||||
|
||||
if (bit_cnt == 7) begin
|
||||
bit_cnt <= 0;
|
||||
rx_buff <= {rx_shift[6:0], mosi};
|
||||
if (cs) begin
|
||||
rx_shift <= 0;
|
||||
rx_buff <= 0;
|
||||
bit_cnt <= 0;
|
||||
end else begin
|
||||
rx_shift <= {rx_shift[6:0], mosi};
|
||||
bit_cnt <= bit_cnt + 1;
|
||||
|
||||
if (bit_cnt == 7) begin
|
||||
bit_cnt <= 0;
|
||||
rx_buff <= {rx_shift[6:0], mosi};
|
||||
byte_ready <= 1;
|
||||
end else
|
||||
end else begin
|
||||
byte_ready <= 0;
|
||||
end // else: !if(cs)
|
||||
end
|
||||
end // else: !if(cs)
|
||||
end // else: !if(rst)
|
||||
|
||||
$display("[%0d] current rx_shift: %b", $time, rx_shift);
|
||||
$display("[%0d] current bit_cnt: %0d", $time, bit_cnt);
|
||||
$display("[%0d] current rx_buff: %b", $time, rx_buff);
|
||||
end // always_ff @ (posedge sclk)
|
||||
|
||||
always_ff @ (posedge sclk_falling_edge) begin
|
||||
|
||||
shortint idle_cntdn;
|
||||
logic rx_drained;
|
||||
|
||||
always_ff @ (posedge sys_clk or rst) begin
|
||||
if (rst) begin
|
||||
tx_shift <= 0;
|
||||
rx_drained <= 0;
|
||||
rx_pkt_addr <= '1;
|
||||
rx_byte <= '0;
|
||||
rx_valid <= 0;
|
||||
idle_cntdn <= 0;
|
||||
end else begin
|
||||
if (!rx_drained && byte_ready) begin
|
||||
rx_byte <= rx_buff;
|
||||
rx_valid <= 1;
|
||||
idle_cntdn <= INTERFACE_IDLE_COUNTDOWN;
|
||||
rx_drained <= 1;
|
||||
rx_pkt_addr <= rx_pkt_addr + 1;
|
||||
end else if (!byte_ready) begin
|
||||
rx_drained <= 0;
|
||||
if (!(|idle_cntdn)) begin
|
||||
rx_valid <= 0;
|
||||
end else begin
|
||||
idle_cntdn <= idle_cntdn - 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
else begin
|
||||
if (cs) begin
|
||||
tx_shift <= 0;
|
||||
end else begin
|
||||
if (bit_cnt == 0) begin
|
||||
tx_shift <= rx_buff[7:0];
|
||||
end else begin
|
||||
tx_shift <= {tx_shift[6:0], 1'b0};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @ (posedge sclk_falling_edge or rst) begin
|
||||
if (rst) begin
|
||||
tx_shift <= 8'b00101010;
|
||||
end else begin
|
||||
if (cs) begin
|
||||
tx_shift <= 0;
|
||||
end else begin
|
||||
if (bit_cnt == 0) begin
|
||||
tx_shift <= rx_buff[7:0];
|
||||
end else begin
|
||||
tx_shift <= {tx_shift[6:0], 1'b0};
|
||||
end
|
||||
end
|
||||
end // else: !if(rst)
|
||||
$display("last bit sent: %b", miso);
|
||||
$display("[%0d] current tx_shift: %b", $time, tx_shift);
|
||||
@ -89,75 +115,19 @@ module spi_interface(
|
||||
end // always_ff @ (negedge sclk)
|
||||
|
||||
assign miso = tx_shift[7];
|
||||
|
||||
// RX and TX logic
|
||||
logic [9:0] rx_queue_head = 0;
|
||||
logic [9:0] rx_queue_tail = 0;
|
||||
logic [10:0] rx_size = 0;
|
||||
logic rx_queue_write = 0;
|
||||
logic [7:0] rx_read;
|
||||
logic [7:0] dest_read;
|
||||
logic packet_sending;
|
||||
logic rx_queue_empty;
|
||||
assign rx_size = (rx_queue_tail + 11'd1024 - rx_queue_head) & 11'h3FF;
|
||||
assign rx_queue_empty = ~(|rx_size);
|
||||
|
||||
rx_queue_bram rx_queue (.sys_clk(sys_clk),
|
||||
.write_enable(rx_queue_write),
|
||||
.read_addr(rx_queue_head),
|
||||
.write_addr(rx_queue_tail),
|
||||
.write_data(rx_buff),
|
||||
.read_data(rx_read),
|
||||
.read_dest(dest_read));
|
||||
|
||||
always_ff @ (posedge sys_clk) begin
|
||||
if (rst) begin
|
||||
rx_queue_head <= '0;
|
||||
rx_queue_tail <= '0;
|
||||
rx_queue_write <= '0;
|
||||
rx_read <= '0;
|
||||
packet_sending <= 0;
|
||||
end else begin
|
||||
if (byte_ready)
|
||||
rx_queue_write <= 1;
|
||||
if (rx_queue_write) begin
|
||||
rx_queue_write <= 0;
|
||||
rx_queue_tail <= rx_queue_tail + 1;
|
||||
end
|
||||
if (!packet_sending) begin
|
||||
if (rx_size > 2 && rx_ready) begin
|
||||
rx_byte <= rx_read;
|
||||
rx_dest <= dest_read;
|
||||
rx_valid <= 1;
|
||||
end else
|
||||
rx_valid <= 0;
|
||||
end else begin
|
||||
if (is_packet_complete(rx_queue_head, packet_size))
|
||||
packet_sending <= 0;
|
||||
else if (rx_size > 0) begin
|
||||
rx_byte <= rx_read;
|
||||
rx_dest <= dest_read;
|
||||
rx_valid <= 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end // always_ff @ (posedge sys_clk)
|
||||
|
||||
logic [13:0] tx_queue_head;
|
||||
logic [13:0] tx_queue_tail;
|
||||
|
||||
|
||||
endmodule // spi_interface
|
||||
|
||||
module async_get_clk_edges(
|
||||
input logic rst,
|
||||
input logic ext_clk,
|
||||
input logic sys_clk,
|
||||
output logic clk_rising_edge,
|
||||
output logic clk_falling_edge);
|
||||
input logic ext_clk,
|
||||
input logic sys_clk,
|
||||
output logic clk_rising_edge,
|
||||
output logic clk_falling_edge);
|
||||
timeunit 1ns;
|
||||
timeprecision 1ps;
|
||||
`ifdef SYNC_2FF
|
||||
|
||||
logic sync_0 = 0;
|
||||
logic sync_1 = 0;
|
||||
|
||||
@ -173,71 +143,4 @@ module async_get_clk_edges(
|
||||
|
||||
assign clk_rising_edge = sync_0 & ~sync_1;
|
||||
assign clk_falling_edge = ~sync_0 & sync_1;
|
||||
`else // !`ifdef SYNC_2FF
|
||||
logic [2:0] clk_sync = 0;
|
||||
|
||||
always_ff @ (posedge sys_clk) begin
|
||||
if (rst)
|
||||
clk_sync <= {clk_sync[1:0], ext_clk};
|
||||
end
|
||||
|
||||
assign clk_rising_edge = (clk_sync[2:1] == 2'b01);
|
||||
assign clk_falling_edge = (clk_sync[2:1] == 2'b10);
|
||||
`endif // !`ifdef SYNC_2FF
|
||||
endmodule // async_get_clk_edges
|
||||
|
||||
module rx_queue_bram (
|
||||
input logic sys_clk,
|
||||
input logic write_enable,
|
||||
input logic [9:0] read_addr,
|
||||
input logic [9:0] write_addr,
|
||||
input logic [7:0] write_data,
|
||||
output logic [7:0] read_data,
|
||||
output logic [7:0] read_dest);
|
||||
timeunit 1ns;
|
||||
timeprecision 1ps;
|
||||
|
||||
|
||||
logic [7:0] mem [1023:0];
|
||||
|
||||
always_ff @ (posedge sys_clk) begin
|
||||
if (write_enable)
|
||||
mem[write_addr] <= write_data;
|
||||
read_data <= mem[read_addr];
|
||||
read_dest <= mem[read_addr + 1];
|
||||
end
|
||||
|
||||
endmodule // rx_queue_bram
|
||||
|
||||
module tx_queue_bram(input logic sys_clk,
|
||||
input logic write_enable,
|
||||
input logic [13:0] read_addr,
|
||||
input logic [13:0] write_addr,
|
||||
input logic [7:0] write_data,
|
||||
output logic [7:0] read_data);
|
||||
timeunit 1ns;
|
||||
timeprecision 1ps;
|
||||
|
||||
logic [7:0] mem [16 * 1023:0];
|
||||
|
||||
always_ff @ (posedge sys_clk) begin
|
||||
if (write_enable)
|
||||
mem[write_addr] <= write_data;
|
||||
read_data <= mem[read_addr];
|
||||
end
|
||||
|
||||
endmodule // tx_queue_bram
|
||||
|
||||
function automatic logic is_packet_complete(input logic [9:0] head,
|
||||
input logic [1:0] packet_size);
|
||||
case(packet_size)
|
||||
2'b00:
|
||||
return &(head & 'd64);
|
||||
2'b01:
|
||||
return &(head & 'd128);
|
||||
2'b10:
|
||||
return &(head & 'd256);
|
||||
2'b11:
|
||||
return &head;
|
||||
endcase // case (packet_size)
|
||||
endfunction // packet_complete
|
||||
|
Reference in New Issue
Block a user