Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module spi(
- input CLOCK_50,
- inout [35:0] GPIO_0,
- output reg [17:0] LEDR,
- output reg [6:0] HEX0, HEX1, HEX2, HEX4
- );
- wire [6:0] h0, h1, h2;
- hex_7seg(byte_data_received[3:0],h0);
- hex_7seg(byte_data_received[7:4],h1);
- hex_7seg(bitcnt,h2);
- always @(*) begin
- HEX0 <= h0;
- HEX1 <= h1;
- HEX4 <= h2;
- end
- initial begin
- LEDR[0] = 0;
- LEDR[1] = 0;
- end
- reg [2:0] SCKr; always @(posedge CLOCK_50) SCKr <= {SCKr[1:0], GPIO_0[0]};
- wire SCK_risingedge = (SCKr[2:1]==2'b01); // now we can detect SCK rising edges
- wire SCK_fallingedge = (SCKr[2:1]==2'b10); // and falling edges
- // same thing for SSEL
- reg [2:0] SSELr; always @(posedge CLOCK_50) SSELr <= {SSELr[1:0], GPIO_0[1]};
- wire SSEL_active = ~SSELr[1]; // SSEL is active low
- wire SSEL_startmessage = (SSELr[2:1]==2'b10); // message starts at falling edge
- wire SSEL_endmessage = (SSELr[2:1]==2'b01); // message stops at rising edge
- // and for MOSI
- reg [1:0] MOSIr; always @(posedge CLOCK_50) MOSIr <= {MOSIr[0], GPIO_0[2]};
- wire MOSI_data = MOSIr[1];
- // we handle SPI in 8-bits format, so we need a 3 bits counter to count the bits as they come in
- reg [2:0] bitcnt;
- reg byte_received; // high when a byte has been received
- reg [7:0] byte_data_received;
- always @(posedge CLOCK_50)
- begin
- if(~SSEL_active) begin
- bitcnt <= 3'b000;
- end
- else
- if(SCK_risingedge) begin
- bitcnt <= bitcnt + 3'b001;
- // implement a shift-left register (since we receive the data MSB first)
- byte_data_received <= {byte_data_received[6:0], MOSI_data};
- end
- end
- always @(posedge CLOCK_50) byte_received <= SSEL_active && SCK_risingedge && (bitcnt==3'b111);
- // we use the LSB of the data received to control an LED
- always @(posedge CLOCK_50) if(byte_received) LEDR[17] <= byte_data_received[0];
- /*always @(posedge GPIO_0[0]) begin
- LEDR[0] = ~LEDR[0];
- LEDR[3] = SCK_risingedge;
- LEDR[4] = SCK_fallingedge;
- LEDR[5] = SSEL_active;
- LEDR[6] = SSEL_endmessage;
- end
- always @(posedge GPIO_0[1]) begin
- LEDR[1] = ~LEDR[1];
- end
- always @(posedge GPIO_0[2]) begin
- LEDR[2] = ~LEDR[2];
- end*/
- reg [7:0] byte_data_sent;
- reg [7:0] cnt;
- always @(posedge CLOCK_50) if(SSEL_startmessage) cnt<=cnt+8'h1; // count the messages
- always @(posedge CLOCK_50)
- if(SSEL_active)
- begin
- if(SSEL_startmessage)
- byte_data_sent <= 8'h03; // first byte sent in a message is the message count
- else
- if(SCK_fallingedge)
- begin
- if(bitcnt==3'b000)
- byte_data_sent <= 8'h00; // after that, we send 0s
- else
- byte_data_sent <= {byte_data_sent[6:0], 1'b0};
- end
- end
- assign GPIO_0[3] = byte_data_sent[7]; // send MSB first
- // we assume that there is only one slave on the SPI bus
- // so we don't bother with a tri-state buffer for MISO
- // otherwise we would need to tri-state MISO when SSEL is inactive
- endmodule
Advertisement
Add Comment
Please, Sign In to add comment