Guest User

Untitled

a guest
Jul 18th, 2018
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. module spi (
  2.         input clk,
  3.         input clk_en, // assumed to get the correct enables for the freq we need 100Khz etc.
  4.  
  5.         input reset,
  6.         input enable,
  7.  
  8.         input [39:0] cmd_data, // command data.
  9.  
  10.         output reg rsp_rdy, // read pulse
  11.         output [15:0] rsp_count, // bytes read this respose cycle.
  12.         output reg [7:0] rsp_data, // response data.
  13.  
  14.         // raw spi bus.
  15.  
  16.         output spi_clk,
  17.         input  spi_miso,
  18.         output spi_mosi,
  19.         output spi_cs_n);
  20.  
  21. // states
  22. localparam idle=0, warmup=1, cmd=2, rsp=3;
  23.  
  24. // warmup counter
  25.  
  26. wire warmup_complete;
  27. reg [15:0] warmup_count = 16'd0;
  28.  
  29. // spi clock register
  30. reg clk_r = 1'b0;
  31.  
  32. reg [18:0] shift_count = 19'd0;
  33. reg [47:0] shift_reg = {48{1'b1}};
  34.  
  35. reg [1:0] mode = idle;
  36. reg [1:0] mode_r = idle;
  37.  
  38. always @(posedge clk)
  39. begin
  40.  
  41.     if (reset) begin
  42.    
  43.         clk_r <= 1'b0;
  44.         mode <= warmup;
  45.        
  46.         shift_reg = {48{1'b1}};
  47.  
  48.         shift_count = 19'd0;
  49.         warmup_count <= 16'd0;
  50.        
  51.     end else if (clk_en) begin
  52.      
  53.         case (mode)
  54.        
  55.             idle: begin // idle logic
  56.                
  57.                 byte_count <= 3'd0;
  58.                
  59.                 if (enable) begin
  60.                     mode <= cmd; // now we start clocking out the command
  61.                     shift_reg <= cmd_data;     
  62.                 end
  63.                
  64.             end
  65.  
  66.             warmup: begin // warmup logic
  67.            
  68.                 if (warmup_complete & !clk_r) begin
  69.                     mode <= idle;
  70.                 end else begin
  71.                     warmup_count <= warmup_count + 16'd1;
  72.                 end
  73.                
  74.             end
  75.  
  76.             cmd: begin // send a command. 6 bytes
  77.                
  78.                 if (!clk_r) begin
  79.                     shift_reg <= {shift_reg[46:0], 1'b1};
  80.                 end
  81.                
  82.                 // if we've shifted out 6 bytes then we're done.
  83.                 if (shift_counter == {16'd5,3'b111}) begin
  84.                     mode <= read;
  85.                 end
  86.                
  87.             end
  88.            
  89.             read: begin
  90.                
  91.                 if (!clk_r) begin
  92.                
  93.                     shift_reg[7:0] <= {shift_reg[6:0], spi_miso};
  94.                    
  95.                     if (shift_count[2:0] == 3'b111) begin
  96.                         rsp_data <= {shift_reg[6:0], spi_miso};
  97.                         rsp_rdy <= 1'b1;
  98.                     end
  99.                    
  100.                 end else begin
  101.                     rsp_rdy <= 1'b0;
  102.                 end
  103.                
  104.                 if (!enable) begin
  105.                     mode <= idle;
  106.                 end
  107.                
  108.             end
  109.            
  110.            
  111.         endcase
  112.    
  113.         // clock output
  114.         if ((mode != idle) | (shift_count[2:0] != 3'd0))  begin
  115.            
  116.             clk_r <= !clk_r;
  117.            
  118.             if (clk_r) begin
  119.                
  120.                 // if the state mode changes reset the count.
  121.                
  122.                 if (mode_r != mode) begin
  123.                     shift_count <= 19'd0;
  124.                 end else begin
  125.                     shift_count <= shift_count + 19'd1;
  126.                 end
  127.                
  128.                 mode_r <= mode;
  129.             end
  130.            
  131.         end else begin
  132.             clk_r <= 1'b0;
  133.         end
  134.        
  135.     end
  136. end
  137.  
  138. assign warmup_complete = warmup_count >= 80 * 8;
  139. assign spi_mosi = shift_reg[47];
  140. assign spi_cs_n = !warmup_complete;
  141. assign rsp_count = shift_count[18:3] & {16{(mode == read)}};
  142.  
  143. endmodule
Add Comment
Please, Sign In to add comment