`timescale 1ns/1ns
module lcd_spi_top_tb();
reg clk_x2_i;
reg rst_i;
wire spi_cs;
wire spi_scl;
wire spi_mosi;
wire spi_miso;
wire spi_init_done;
initial begin
clk_x2_i=0;
rst_i=0;
#1000;
rst_i=1;
#1000;
@(posedge spi_init_done)
$stop;
end
always #125 clk_x2_i<=~clk_x2_i;
lcd_spi_top
#(
.SPI_IN_WIDTH (6'd16),//spi 输入位数
.SPI_OUT_WIDTH (6'd16),//SPI 输出位数
.SPI_CPOL (1'b0),//空闲状态SCL电平 0:SCL=0 1:SCL=1
.SPI_CPHA (1'b0) //SPI数据在哪个SCL边沿有效 0:数据在SCL第一个边沿有效,1:数据在SCL第二个边沿有效,
)
lcd_spi_top_inst
(
.clk_x2_i (clk_x2_i ),
.rst_i (rst_i ),
.spi_cs_o (spi_cs ),
.spi_scl_o (spi_scl ),
.spi_mosi (spi_mosi ),
.spi_miso (spi_miso ),
.spi_init_done(spi_init_done)
);
endmodule
module lcd_spi_top
#(
parameter [5:0]SPI_IN_WIDTH =6'd16,//spi 输入位数
parameter [5:0]SPI_OUT_WIDTH =6'd16,//SPI 输出位数
parameter [0:0]SPI_CPOL=1'b0,//空闲状态SCL电平 0:SCL=0 1:SCL=1
parameter [0:0]SPI_CPHA=1'b0, //SPI数据在哪个SCL边沿有效 0:数据在SCL第一个边沿有效,1:数据在SCL第二个边沿有效,
parameter [5:0]CS_F_DELAY=6'd1,
parameter [5:0]CS_B_DELAY=6'd1
)
(
input wire [0:0] clk_x2_i, //SPI输出时钟的2倍时钟输入
input wire [0:0] rst_i, //复位信号输入
output reg [0:0] lcd_rst, //显示屏复位
output wire [0:0] spi_cs_o, //
output wire [0:0] spi_scl_o,
output wire [0:0] spi_mosi,
input wire [0:0] spi_miso,
output reg [0:0] spi_init_done
);
localparam [7:0] SPI_CODE_NUM=8'D207 ;
reg [15:0] rom [SPI_CODE_NUM-1:0];
initial begin
rom[0 ]=16'h0003;
rom[1 ]=16'h0121;
rom[2 ]=16'h0227;
rom[3 ]=16'h031B;
rom[4 ]=16'h04F4;
rom[5 ]=16'h0507;
rom[6 ]=16'h0790;
rom[7 ]=16'h081B;
rom[8 ]=16'h0903;
rom[9 ]=16'h0A25;
rom[10 ]=16'h0B20;
rom[11 ]=16'h0C20;
rom[12 ]=16'h0D0D;
rom[13 ]=16'h0E20;
rom[14 ]=16'h0F20;
rom[15 ]=16'h1040;
rom[16 ]=16'h1140;
rom[17 ]=16'h1240;
rom[18 ]=16'h1340;
rom[19 ]=16'h1408;
rom[20 ]=16'h1506;
rom[21 ]=16'h16B4;
rom[22 ]=16'h1700;
rom[23 ]=16'h1888;
rom[24 ]=16'h19FF;
rom[25 ]=16'h1A00;
rom[26 ]=16'h1B80;
rom[27 ]=16'h1C00;
rom[28 ]=16'h1D00;
rom[29 ]=16'h1E00;
rom[30 ]=16'h1F3F;
rom[31 ]=16'h2085;
rom[32 ]=16'h2189;
rom[33 ]=16'h2287;
rom[34 ]=16'h2387;
rom[35 ]=16'h2487;
rom[36 ]=16'h258C;
rom[37 ]=16'h2683;
rom[38 ]=16'h270C;
rom[39 ]=16'h282B;
rom[40 ]=16'h2923;
rom[41 ]=16'h2A28;
rom[42 ]=16'h2B28;
rom[43 ]=16'h2C30;
rom[44 ]=16'h2D3B;
rom[45 ]=16'h2E00;
rom[46 ]=16'h2F08;
rom[47 ]=16'h3000;
rom[48 ]=16'h3100;
rom[49 ]=16'h3200;
rom[50 ]=16'h3300;
rom[51 ]=16'h3400;
rom[52 ]=16'h3500;
rom[53 ]=16'h3600;
rom[54 ]=16'h3700;
rom[55 ]=16'h3800;
rom[56 ]=16'h3900;
rom[57 ]=16'h3A00;
rom[58 ]=16'h3B00;
rom[59 ]=16'h3C00;
rom[60 ]=16'h3D00;
rom[61 ]=16'h3E00;
rom[62 ]=16'h3F00;
rom[63 ]=16'h4000;
rom[64 ]=16'h418E;
rom[65 ]=16'h42A0;
rom[66 ]=16'h4300;
rom[67 ]=16'h4429;
rom[68 ]=16'h0121;
rom[69 ]=16'h0227;
rom[70 ]=16'h0790;
rom[71 ]=16'h0A25;
rom[72 ]=16'h0B20;
rom[73 ]=16'h0C20;
rom[74 ]=16'h0D0D;
rom[75 ]=16'h0E20;
rom[76 ]=16'h0F20;
rom[77 ]=16'h1040;
rom[78 ]=16'h113A;
rom[79 ]=16'h122C;
rom[80 ]=16'h1340;
rom[81 ]=16'h2085;
rom[82 ]=16'h2189;
rom[83 ]=16'h2287;
rom[84 ]=16'h2387;
rom[85 ]=16'h2487;
rom[86 ]=16'h258C;
rom[87 ]=16'h2683;
rom[88 ]=16'h270C;
rom[89 ]=16'h282B;
rom[90 ]=16'h2923;
rom[91 ]=16'h2A28;
rom[92 ]=16'h2B28;
rom[93 ]=16'h2C30;
rom[94 ]=16'h2D3B;
rom[95 ]=16'h2E00;
rom[96 ]=16'h2F08;
rom[97 ]=16'h4000;
rom[98 ]=16'h418E;
rom[99 ]=16'h42A0;
rom[100]=16'h4300;
rom[101]=16'h4429;
rom[102]=16'h0600;
rom[103]=16'h0000;
rom[104]=16'h0003;
rom[105]=16'h0121;
rom[106]=16'h0227;
rom[107]=16'h031B;
rom[108]=16'h04F4;
rom[109]=16'h0507;
rom[110]=16'h0790;
rom[111]=16'h081B;
rom[112]=16'h0903;
rom[113]=16'h0A25;
rom[114]=16'h0B20;
rom[115]=16'h0C20;
rom[116]=16'h0D0D;
rom[117]=16'h0E20;
rom[118]=16'h0F20;
rom[119]=16'h1040;
rom[120]=16'h1140;
rom[121]=16'h1240;
rom[122]=16'h1340;
rom[123]=16'h1408;
rom[124]=16'h1506;
rom[125]=16'h16B4;
rom[126]=16'h1700;
rom[127]=16'h1888;
rom[128]=16'h19FF;
rom[129]=16'h1A00;
rom[130]=16'h1B80;
rom[131]=16'h1C00;
rom[132]=16'h1D00;
rom[133]=16'h1E00;
rom[134]=16'h1F3F;
rom[135]=16'h2085;
rom[136]=16'h2189;
rom[137]=16'h2287;
rom[138]=16'h2387;
rom[139]=16'h2487;
rom[140]=16'h258C;
rom[141]=16'h2683;
rom[142]=16'h270C;
rom[143]=16'h282B;
rom[144]=16'h2923;
rom[145]=16'h2A28;
rom[146]=16'h2B28;
rom[147]=16'h2C30;
rom[148]=16'h2D3B;
rom[149]=16'h2E00;
rom[150]=16'h2F08;
rom[151]=16'h3000;
rom[152]=16'h3100;
rom[153]=16'h3200;
rom[154]=16'h3300;
rom[155]=16'h3400;
rom[156]=16'h3500;
rom[157]=16'h3600;
rom[158]=16'h3700;
rom[159]=16'h3800;
rom[160]=16'h3900;
rom[161]=16'h3A00;
rom[162]=16'h3B00;
rom[163]=16'h3C00;
rom[164]=16'h3D00;
rom[165]=16'h3E00;
rom[166]=16'h3F00;
rom[167]=16'h4000;
rom[168]=16'h418E;
rom[169]=16'h42A0;
rom[170]=16'h4300;
rom[171]=16'h4429;
rom[172]=16'h0121;
rom[173]=16'h0227;
rom[174]=16'h0790;
rom[175]=16'h0A25;
rom[176]=16'h0B20;
rom[177]=16'h0C20;
rom[178]=16'h0D0D;
rom[179]=16'h0E20;
rom[180]=16'h0F20;
rom[181]=16'h1040;
rom[182]=16'h113A;
rom[183]=16'h122C;
rom[184]=16'h1340;
rom[185]=16'h2085;
rom[186]=16'h2189;
rom[187]=16'h2287;
rom[188]=16'h2387;
rom[189]=16'h2487;
rom[190]=16'h258C;
rom[191]=16'h2683;
rom[192]=16'h270C;
rom[193]=16'h282B;
rom[194]=16'h2923;
rom[195]=16'h2A28;
rom[196]=16'h2B28;
rom[197]=16'h2C30;
rom[198]=16'h2D3B;
rom[199]=16'h2E00;
rom[200]=16'h2F08;
rom[201]=16'h4000;
rom[202]=16'h418E;
rom[203]=16'h42A0;
rom[204]=16'h4300;
rom[205]=16'h4429;
rom[206]=16'h0600;
end
localparam [3:0]SEND_IDLE =0000;
localparam [3:0]LCD_RESET =0001;
localparam [3:0]SEND_CMD =0010;
localparam [3:0]SEND_CMD1 =0110;
localparam [3:0]SEND_DELAY =0111;
localparam [3:0]SEND_END =0101;
reg [31:0] spi_data_i;
reg spi_start;
wire spi_done;
wire spi_busy;
wire [31:0] spi_data_o;
reg [5:0] state;
reg [10:0] reg_cnt;
reg [20:0] delay_cnt;
parameter [20:0] DELAY_50MS=21'd200_000; //50MS*1000*1000/250NS=21'd200_000
parameter [20:0] DELAY_120MS=21'd480_000; //120MS*1000*1000/250NS=21'd480_000
always @(negedge clk_x2_i or negedge rst_i )
begin
if(rst_i==1'b0)
begin
state<=SEND_IDLE;
spi_data_i<=32'B0;
spi_start<=1'B0;
reg_cnt<=11'd0;
delay_cnt<=20'd0;
spi_init_done<=1'b0;
lcd_rst<=1'b0;
end
else
begin
case(state)
SEND_IDLE : begin
if(delay_cnt<DELAY_50MS)
begin
state<=SEND_IDLE;
lcd_rst<=1'b0;
delay_cnt<=delay_cnt+1'd1;
end
else
begin
state<=LCD_RESET;
lcd_rst<=1'b1;
delay_cnt<=21'd0;
end
end
LCD_RESET : begin
if(delay_cnt<DELAY_120MS)
begin
state<=LCD_RESET;
lcd_rst<=1'b1;
delay_cnt<=delay_cnt+1'd1;
end
else
begin
state<=SEND_CMD;
delay_cnt<=20'd0;
end
end
SEND_CMD :begin
if(spi_busy==1'b0)
begin
if(reg_cnt<SPI_CODE_NUM )
begin
spi_data_i<=rom[reg_cnt];
spi_start<=1'b1;
state<=SEND_CMD1;
end
else
begin
state<=SEND_END;
spi_init_done<=1'b1;
reg_cnt<=11'd0;
spi_start<=1'b0;
end
end
else
begin
state<=state;
reg_cnt<=reg_cnt;
spi_start<=1'B0;
end
end
SEND_CMD1 :begin
if(spi_busy==1'b1)
begin
reg_cnt<=reg_cnt+1'd1;
spi_start<=1'b0;
state<=SEND_CMD;
end
else
begin
state<=SEND_CMD;
end
end
SEND_DELAY :begin
if(delay_cnt<DELAY_120MS)
begin
delay_cnt<=delay_cnt+1'd1;
reg_cnt<=reg_cnt;
end
else
begin
state<=SEND_CMD;
delay_cnt<=10'd0;
reg_cnt<=reg_cnt;
end
spi_start<=1'b0;
end
SEND_END :begin
spi_data_i<=32'B0;
spi_start<=1'B0;
reg_cnt<=11'd0;
spi_init_done<=1'b1;
state<=SEND_END;
end
default : begin
spi_data_i<=32'B0;
spi_start<=1'B0;
reg_cnt<=8'd0;
state<=SEND_END;
end
endcase
end
end
lcd_spi_m
#(
.SPI_IN_WIDTH (SPI_IN_WIDTH),//spi 输入位数
.SPI_OUT_WIDTH (SPI_OUT_WIDTH),//SPI 输出位数
.SPI_CPOL (SPI_CPOL),//空闲状态SCL电平 0:SCL=0 1:SCL=1
.SPI_CPHA (SPI_CPHA), //SPI数据在哪个SCL边沿有效 0:数据在SCL第一个边沿有效,1:数据在SCL第二个边沿有效,
.CS_F_DELAY (6'd1),
.CS_B_DELAY (6'd1)
)
lcd_spi_m_inst
(
.rst_n_i (rst_i) , //复位输入,低电平复位
.spi_x2clk_i(clk_x2_i) ,//SPI系统时钟 为SCL输出时钟的两倍
.spi_data_i (spi_data_i),//输入32位要从MOSI发送出去的数据
.spi_start (spi_start) , //单次发送开始,把数据送到spi_data_i 并把spi_start维技一个周期的高电平
.spi_miso_i (spi_miso) ,//主机接收从机输出引脚
.spi_done (spi_done) ,//SPI完成一次传输并从spi_data_o输出读到的数据
.spi_busy (spi_busy) ,//SPI忙信号输出,在忙状态时不接收外部数据,高表示忙
.spi_cs_o (spi_cs_o) ,//SPI片选信号输出低有效
.spi_scl_o (spi_scl_o) ,//SPI 时钟信号输出,请结合CPOL CPHA分析有效性
.spi_mosi_o (spi_mosi),//SPI主机输出从机输入接口
.spi_data_o (spi_data_o) //从从机读到的数据在SPI_DONE为高时为有效数据
);
endmodule
1 //SPI主程序
2 //功能:完成32位以内SPI接口的数据双向通信
3 module lcd_spi_m
4 #(
5 parameter [5:0]SPI_IN_WIDTH =6'd9,//spi 输入位数
6 parameter [5:0]SPI_OUT_WIDTH =6'd9,//SPI 输出位数
7 parameter [0:0]SPI_CPOL=1'b0,//空闲状态SCL电平 0:SCL=0 1:SCL=1
8 parameter [0:0]SPI_CPHA=1'b1, //SPI数据在哪个SCL边沿有效 0:数据在SCL第一个边沿有效,1:数据在SCL第二个边沿有效,
9 parameter [5:0]CS_F_DELAY=6'D1, //CS前面延时
10 parameter [5:0]CS_B_DELAY=6'D1 //CS后面延时
11
12
13 )
14 (
15 input wire [0:0] rst_n_i, //复位输入,低电平复位
16 input wire [0:0] spi_x2clk_i,//SPI系统时钟 为SCL输出时钟的两???
17 input wire [31:0] spi_data_i,//输入32位要从MOSI发送出去的数据
18 input wire [0:0] spi_start, //单次发送开始,把数据送到spi_data_i 并把spi_start维技一个周期的高电???
19 input wire [0:0] spi_miso_i,//主机接收从机输出引脚
20 output reg [0:0] spi_done,//SPI完成一次传输并从spi_data_o输出读到的数???
21 output reg [0:0] spi_busy,//SPI忙信号输出,在忙状态时不接收外部数据,高表示忙
22 output reg [0:0] spi_cs_o,//SPI片选信号输出低有效
23 output reg [0:0] spi_scl_o,//SPI 时钟信号输出,请结合CPOL CPHA分析有效???
24 output reg [0:0] spi_mosi_o,//SPI主机输出从机输入接口
25 output reg [31:0] spi_data_o//从从机读到的数据在SPI_DONE为高时为有效数据
26
27
28 );
29
30
31 localparam [7:0] CS_F_CNT=CS_F_DELAY+CS_F_DELAY; //CS前面延时
32 localparam [7:0] CS_B_CNT=CS_B_DELAY+CS_B_DELAY; //CS后面延时
33 localparam [7:0] WIDTH_MAX=(SPI_IN_WIDTH>SPI_OUT_WIDTH)? (SPI_IN_WIDTH*2'D2+CS_F_CNT+CS_B_CNT) :(SPI_OUT_WIDTH*2'D2+CS_F_CNT+CS_B_CNT);
34
35
36
37
38
39 //产生spi_x2clk_i时钟计数
40 reg [6:0] clk_cnt;
41 always @(posedge spi_x2clk_i or negedge rst_n_i)
42 begin
43 if(rst_n_i==1'b0)
44 clk_cnt<=6'd0;
45 else if(spi_busy==1'b1 )
46 begin
47 if(clk_cnt<WIDTH_MAX)
48 clk_cnt<=clk_cnt+1'd1;
49 else
50 clk_cnt<=7'd0;
51 end
52 else
53 clk_cnt<=7'd0;
54 end
55
56 //输出SPI_CS信号
57 always @(posedge spi_x2clk_i or negedge rst_n_i)
58 begin
59 if(rst_n_i==1'b0)
60 spi_cs_o<=1'b1;
61 else if(spi_start==1'b1 && spi_busy==1'b0)
62 spi_cs_o<=1'b0;
63 else if(clk_cnt<(WIDTH_MAX-1'd1))
64 spi_cs_o<=spi_cs_o;
65 else
66 spi_cs_o<=1'b1;
67 end
68
69
70
71
72 //输出spi_scl信号
73 always @(posedge spi_x2clk_i or negedge rst_n_i)
74 begin
75 if(rst_n_i==1'b0)
76 begin
77 if(SPI_CPOL==1'b0)
78 begin spi_scl_o<=1'b0; end
79 else
80 begin spi_scl_o<=1'b1; end
81 spi_done<=1'b0;
82 end
83 else if(clk_cnt>=CS_F_CNT-1'd1 && clk_cnt<(WIDTH_MAX-CS_B_CNT-1'd1))
84 begin
85 spi_scl_o<=~spi_scl_o;
86 end
87 else if(clk_cnt>=WIDTH_MAX-1'd1)
88 begin
89 spi_done<=1'b1;
90
91 end
92 else
93 begin
94 if(SPI_CPOL==1'b0)
95 spi_scl_o<=1'b0;
96 else
97 spi_scl_o<=1'b1;
98 spi_done<=1'b0;
99
100 end
101 end
102 //在spi_start???时捕获数???
103 reg [31:0] temp_data_i;
104 //输出SPI_MOSI信号
105 always @(posedge spi_x2clk_i or negedge rst_n_i)
106 begin
107 if(rst_n_i==1'b0)
108 begin
109 spi_mosi_o<=1'b0;
110 spi_busy<=1'b0;
111 temp_data_i<=32'b0;
112 end
113 else if(spi_start==1'b1 && spi_busy==1'b0) //在spi_start???时捕获数???
114 begin
115 temp_data_i<=spi_data_i;
116 spi_busy<=1'b1;
117 end
118 else if(spi_done==1'b1)
119 spi_busy<=1'b0;
120 else if(SPI_CPHA==1'b0)
121 begin
122 if((clk_cnt>=(CS_F_CNT-8'd2)) && (clk_cnt<(WIDTH_MAX-CS_B_CNT-CS_F_CNT)) && (clk_cnt%2==0) )
123 begin
124 spi_mosi_o<=temp_data_i[SPI_OUT_WIDTH-1'd1];
125 temp_data_i<={temp_data_i[(SPI_OUT_WIDTH-2'd2):0],temp_data_i[SPI_OUT_WIDTH-1'd1]};
126 end
127 else
128 begin
129 spi_mosi_o<=spi_mosi_o;
130 end
131
132 end
133 else if(SPI_CPHA==1'b1)
134 begin
135 if((clk_cnt>=(CS_F_CNT-8'd1)) && clk_cnt<(WIDTH_MAX-CS_B_CNT-CS_F_CNT) && (clk_cnt%2==1) )
136 begin
137 spi_mosi_o<=temp_data_i[SPI_OUT_WIDTH-1'd1];
138 temp_data_i<={temp_data_i[SPI_OUT_WIDTH-2'd2:0],temp_data_i[SPI_OUT_WIDTH-1'd0]};
139 end
140 else
141 begin
142 spi_mosi_o<=spi_mosi_o;
143 end
144 end
145 else
146 begin
147 spi_mosi_o<=1'b1;
148 end
149
150 end
151
152 //接收SPI_MISO信号
153 always @(posedge spi_x2clk_i or negedge rst_n_i)
154 begin
155 if(rst_n_i==1'b0)
156 spi_data_o<=32'b0;
157 else if(SPI_CPHA==1'b0)
158 begin
159 if((clk_cnt>=CS_F_CNT-8'D1) && (clk_cnt<(WIDTH_MAX-CS_B_CNT)) && (clk_cnt%2==1) )
160 begin
161 spi_data_o<={spi_data_o[30:0],spi_miso_i};
162 end
163 else
164 begin
165 spi_data_o<=spi_data_o;
166 end
167 end
168 else if(SPI_CPHA==1'b1)
169 begin
170 if((clk_cnt>=CS_F_CNT) && (clk_cnt<(WIDTH_MAX-CS_B_CNT)) && (clk_cnt%2==1) )
171 begin
172 spi_data_o<={spi_data_o[30:0],spi_miso_i};
173 end
174 else
175 begin
176 spi_data_o<=spi_data_o;
177 end
178 end
179 else
180 begin
181 spi_data_o<=spi_data_o;
182 end
183
184 end
185
186
187 endmodule
1 //testbench
2 `timescale 1ns/1ns
3 module lcd_spi_m_tb();
4 reg rst_n_i;
5 reg spi_x2clk_i;
6 reg [31:0] spi_data_i;
7 reg spi_start;
8 reg spi_miso_i;
9 wire [0:0] spi_done;
10 wire [0:0] spi_busy;
11 wire [0:0] spi_cs_o;
12 wire [0:0] spi_scl_o;
13 wire [0:0] spi_mosi_o;
14 wire [31:0] spi_data_o;
15
16
17
18 always #50 spi_x2clk_i<=~spi_x2clk_i;
19 initial begin
20 rst_n_i=0;
21 spi_x2clk_i=0;
22 #200;
23 spi_start=0;
24 rst_n_i=1;
25 @(posedge spi_x2clk_i)
26 spi_data_i=16'h121;
27 spi_start=1;
28 @(posedge spi_x2clk_i)
29 spi_start=0;
30 @(posedge spi_done)
31 #200;
32 @(posedge spi_x2clk_i)
33 spi_data_i=16'h0003;
34 spi_start=1;
35 @(posedge spi_x2clk_i)
36 spi_start=0;
37 @(posedge spi_done)
38 #200;
39 @(posedge spi_x2clk_i)
40 spi_data_i=16'hF227;
41 spi_start=1;
42 @(posedge spi_x2clk_i)
43 spi_start=0;
44 @(posedge spi_done)
45 #200;
46 @(posedge spi_x2clk_i)
47 spi_data_i=16'hA31B;
48 spi_start=1;
49 @(posedge spi_x2clk_i)
50 spi_start=0;
51 @(posedge spi_done)
52 $stop;
53 end
54
55 always @(negedge spi_scl_o or negedge rst_n_i )//要根据CPOL CPHA配置 spi_scl_o采样极性
56 begin
57 if(rst_n_i==1'b0)
58 spi_miso_i<=1'b0;
59 else if (spi_cs_o==1'b0 )
60 spi_miso_i<=~spi_miso_i;
61 else
62 spi_miso_i<=1'b0;
63 end
64
65 lcd_spi_m
66 #(
67 .SPI_IN_WIDTH(6'd16),//spi 输入位数
68 .SPI_OUT_WIDTH (6'd16),//SPI 输出位数
69 .SPI_CPOL(1'b1),
70 .SPI_CPHA(1'b1),
71 .CS_F_DELAY(6'd1),
72 .CS_B_DELAY(6'd1)
73
74
75
76 )
77 lcd_spi_m_inst
78 (
79 .rst_n_i (rst_n_i ) ,
80 .spi_x2clk_i (spi_x2clk_i ) ,
81 .spi_data_i (spi_data_i ) ,
82 .spi_start (spi_start ) ,
83 .spi_miso_i (spi_miso_i ) ,
84 .spi_done (spi_done ) ,
85 .spi_busy (spi_busy ) ,
86 .spi_cs_o (spi_cs_o ) ,
87 .spi_scl_o (spi_scl_o ) ,
88 .spi_mosi_o (spi_mosi_o ) ,
89 .spi_data_o (spi_data_o )
90
91 );
92
93 endmodule
![]()
![]()