TheLegace

SPI_DE2

Apr 1st, 2012
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. module spi(
  2.                 input CLOCK_50,
  3.                 inout [35:0] GPIO_0,
  4.                 output reg [17:0] LEDR,
  5.                 output reg [6:0] HEX0, HEX1, HEX2, HEX4
  6. );
  7.  
  8. wire [6:0] h0, h1, h2;
  9.  
  10. hex_7seg(byte_data_received[3:0],h0);
  11. hex_7seg(byte_data_received[7:4],h1);
  12.  
  13. hex_7seg(bitcnt,h2);
  14.  
  15. always @(*) begin
  16.     HEX0 <= h0;
  17.     HEX1 <= h1;
  18.     HEX4 <= h2;
  19. end
  20.  
  21. initial begin
  22.     LEDR[0] = 0;
  23.     LEDR[1] = 0;
  24. end
  25.  
  26. reg [2:0] SCKr;  always @(posedge CLOCK_50) SCKr <= {SCKr[1:0], GPIO_0[0]};
  27. wire SCK_risingedge = (SCKr[2:1]==2'b01);  // now we can detect SCK rising edges
  28. wire SCK_fallingedge = (SCKr[2:1]==2'b10);  // and falling edges
  29.  
  30. // same thing for SSEL
  31. reg [2:0] SSELr;  always @(posedge CLOCK_50) SSELr <= {SSELr[1:0], GPIO_0[1]};
  32. wire SSEL_active = ~SSELr[1];  // SSEL is active low
  33. wire SSEL_startmessage = (SSELr[2:1]==2'b10);  // message starts at falling edge
  34. wire SSEL_endmessage = (SSELr[2:1]==2'b01);  // message stops at rising edge
  35.  
  36. // and for MOSI
  37. reg [1:0] MOSIr;  always @(posedge CLOCK_50) MOSIr <= {MOSIr[0], GPIO_0[2]};
  38. wire MOSI_data = MOSIr[1];
  39.  
  40.  
  41. // we handle SPI in 8-bits format, so we need a 3 bits counter to count the bits as they come in
  42. reg [2:0] bitcnt;
  43.  
  44. reg byte_received;  // high when a byte has been received
  45. reg [7:0] byte_data_received;
  46.  
  47. always @(posedge CLOCK_50)
  48. begin
  49.     if(~SSEL_active) begin
  50.         bitcnt <= 3'b000;
  51.     end
  52.     else
  53.         if(SCK_risingedge) begin
  54.             bitcnt <= bitcnt + 3'b001;
  55.            
  56.             // implement a shift-left register (since we receive the data MSB first)
  57.             byte_data_received <= {byte_data_received[6:0], MOSI_data};
  58.         end
  59. end
  60.  
  61. always @(posedge CLOCK_50) byte_received <= SSEL_active && SCK_risingedge && (bitcnt==3'b111);
  62.  
  63. // we use the LSB of the data received to control an LED
  64. always @(posedge CLOCK_50) if(byte_received) LEDR[17] <= byte_data_received[0];
  65.  
  66. /*always @(posedge GPIO_0[0]) begin
  67.     LEDR[0] = ~LEDR[0];
  68.     LEDR[3] = SCK_risingedge;
  69.     LEDR[4] = SCK_fallingedge;
  70.     LEDR[5] = SSEL_active;
  71.     LEDR[6] = SSEL_endmessage;
  72. end
  73.  
  74. always @(posedge GPIO_0[1]) begin
  75.     LEDR[1] = ~LEDR[1];
  76. end
  77.  
  78. always @(posedge GPIO_0[2]) begin
  79.     LEDR[2] = ~LEDR[2];
  80. end*/
  81.  
  82.  
  83. reg [7:0] byte_data_sent;
  84.  
  85. reg [7:0] cnt;
  86. always @(posedge CLOCK_50) if(SSEL_startmessage) cnt<=cnt+8'h1;  // count the messages
  87.  
  88. always @(posedge CLOCK_50)
  89. if(SSEL_active)
  90. begin
  91.   if(SSEL_startmessage)
  92.     byte_data_sent <= 8'h03;  // first byte sent in a message is the message count
  93.   else
  94.   if(SCK_fallingedge)
  95.   begin
  96.     if(bitcnt==3'b000)
  97.       byte_data_sent <= 8'h00;  // after that, we send 0s
  98.     else
  99.       byte_data_sent <= {byte_data_sent[6:0], 1'b0};
  100.   end
  101. end
  102.  
  103. assign GPIO_0[3] = byte_data_sent[7];  // send MSB first
  104. // we assume that there is only one slave on the SPI bus
  105. // so we don't bother with a tri-state buffer for MISO
  106. // otherwise we would need to tri-state MISO when SSEL is inactive
  107.  
  108. endmodule
Advertisement
Add Comment
Please, Sign In to add comment