Root/lm32/logic/sakc/rtl/wb_spi/wb_spi.v

1//-----------------------------------------------------------------
2// SPI Master
3//-----------------------------------------------------------------
4
5module wb_spi(
6    input clk;
7    input reset;
8    // Wishbone bus
9    input [31:0] wb_adr_i;
10    input [31:0] wb_dat_i;
11    output reg [31:0] wb_dat_o;
12    input [ 3:0] wb_sel_i;
13    input wb_cyc_i;
14    input wb_stb_i;
15    output wb_ack_o;
16    input wb_we_i;
17    // SPI
18    output spi_sck;
19    output spi_mosi;
20    input spi_miso;
21    output reg [7:0] spi_cs;
22);
23
24
25    reg ack;
26    assign wb_ack_o = wb_stb_i & wb_cyc_i & ack;
27
28    wire wb_rd = wb_stb_i & wb_cyc_i & ~ack & ~wb_we_i;
29    wire wb_wr = wb_stb_i & wb_cyc_i & ~ack & wb_we_i;
30
31    
32    reg [2:0] bitcount;
33    reg ilatch;
34    reg run;
35
36    reg sck;
37
38    //prescaler registers for sclk
39    reg [7:0] prescaler;
40    reg [7:0] divisor;
41
42    //data shift register
43    reg [7:0] sreg;
44
45    assign spi_sck = sck;
46    assign spi_mosi = sreg[7];
47
48    always @(posedge clk) begin
49        if (reset == 1'b1) begin
50            ack <= 0;
51            sck <= 1'b0;
52            bitcount <= 3'b000;
53            run <= 1'b0;
54            prescaler <= 8'h00;
55            divisor <= 8'hff;
56        end else begin
57            prescaler <= prescaler + 1;
58            if (prescaler == divisor) begin
59                prescaler <= 8'h00;
60                if (run == 1'b1) begin
61                    sck <= ~sck;
62                    if(sck == 1'b1) begin
63                        bitcount <= bitcount + 1;
64                        if(bitcount == 3'b111) begin
65                            run <= 1'b0;
66                        end
67                        
68                        sreg [7:0] <= {sreg[6:0], ilatch};
69                    end else begin
70                        ilatch <= spi_miso;
71                    end
72                end
73            end
74
75            ack <= wb_stb_i & wb_cyc_i;
76            
77            if (wb_rd) begin // read cycle
78                case (wb_adr_i[5:2])
79                    4'b0000: wb_dat_o <= sreg;
80                    4'b0001: wb_dat_o <= {7'b0000000 , run};
81                endcase
82            end
83            
84            
85            if (wb_wr) begin // write cycle
86                case (wb_adr_i[5:2])
87                    4'b0000: begin
88                            sreg <= wb_dat_i[7:0];
89                            run <= 1'b1;
90                        end
91                    4'b0010:
92                            spi_cs <= wb_dat_i[7:0];
93                    4'b0100:
94                            divisor <= wb_dat_i[7:0];
95                endcase
96            end
97        end
98    end
99
100
101endmodule
102

Archive Download this file

Branches:
master



interactive