当前位置:   article > 正文

FPGA驱动0.96寸OLED(SSD1306)_fpga驱动oled

fpga驱动oled

目录 

一、七针0.96寸OLED驱动原理

二、SSD1306驱动时序

1、GDDRAM内部结构:

(1)页寻址

 (2)水平寻址

 (3)垂直寻址

2、初始化

3、清屏

4、发送数据

三、子模块源码

1、初始化

2、清屏

3、数据

四、top源码

五、仿真结果

六、板级验证


SPI主机写模式FPGA实现详细请见:FPGA实现SPI写模式(用于SSD1603的0.91寸OLED驱动)_LionelZhao的博客-CSDN博客https://blog.csdn.net/LionelZhao/article/details/128553379

一、七针0.96寸OLED驱动原理

        本实验所使用的七针OLED结构图和电路原理图如下:

         所使用的驱动芯片为SSD1306,通讯协议为4线SPI,七针名称与对应的功能列表如下:

 七根管脚分别为:GND、VCC、CS(片选 低电平有效)、DC(数据/命令控制 1数据,0命令)、D0(同步时钟信号sck)、D1(从机接收端MOSI)、RES(OLED清屏信号 低电平有效):

        时序图如下:

二、SSD1306驱动时序

1、GDDRAM内部结构:

        GDDRAM(Graphic Display Data RAM )内部结构如下所示:

         将128*64个像素按8行一个PAGE分为8个PAGE,列SEG0~SEG127,这样通过PAGE和SEG的数值就能将8位长的数据显示在对应的位置上,从上到下为低位到高位,如下图所示。

         GDDRAM三种寻址模式如下所示:

(1)页寻址

        SSD1306默认页寻址模式,通过“20H,02H”命令可以设置寻址模式为页寻址。
  页寻址模式下,寻址只在一页内进行,地址指针不会跳到其他页。每次向GDDRAM写入1Byte显示数据后,列指针会自动+1。当128列都寻址完之后,列指针会重新指向SEG0而页指针仍然保持不变。通过页寻址模式我们可以方便地对一个小区域内数据进行修改。

 (2)水平寻址

       水平寻址模式可以通过指令“20H,00H”来设置。
  水平寻址模式下,每次向GDDRAM写入1Byte数据后,列地址指针自动+1。列指针到达结束列之后会被重置到起始列,而页指针将会+1。页地址指针达到结束页之后,将会自动重置到起始页。

 (3)垂直寻址

       垂直寻址模式可以通过指令“20H,01H”来设置。
  垂直寻址模式下,每次向GDDRAM写入1byte数据之后,页地址指针将会自动+1。页指针到达结束页之后会被重置到0,而列指针将会+1。列地址指针达到结束页之后,将会自动重置到起始列。

2、初始化

        SSD1306驱动过程为:初始化->清屏->发送数据,常见命令如下:

        在上电开始就需要发送控制命令来初始化OLED。

3、清屏

        在发送这一帧数据之前需要先清楚上一帧的数据,只需要遍历PAGE和SEG的所有地址并发送数据8'h00就能实现清屏。

4、发送数据

        与清屏同理,在对应的PAGE和SEG选中的Byte发送相应的数据,这样就能拼凑出想要的图案。

三、子模块源码

1、初始化

        三段式状态机实现,需要配置多少个命令就添加对应数量的状态,在每一个状态发送响应的命令即可。

  1. module OLED_initial(
  2. input clk,//输入时钟
  3. input rst_n,//系统复位
  4. input SPI_done,//SPI发送完成通知
  5. output DC,//1数据 0命令
  6. output initial_done,//初始化完成标志
  7. output SPI_send,//通过SPI发送数据
  8. output reg [7:0] SPI_data//SPI发送的数据
  9. );
  10. //定义初始化所需命令参数
  11. parameter Display_on = 8'haf;//开启显示
  12. parameter Display_off = 8'hae;//关闭显示
  13. parameter Set_display_clk_0 = 8'hd5;//显示时钟分频控制 命令头
  14. parameter Set_display_clk_1 = 8'h80;//100帧/秒
  15. parameter Set_charge_pump_0 = 8'h8d;//电荷泵 命令头
  16. parameter Set_charge_pump_1 = 8'h14;//开启charge pump
  17. parameter Set_contrast_0 = 8'h81;//对比度控制 命令头
  18. parameter Set_contrast_1 = 8'hcf;//207
  19. parameter Set_precharge_0 = 8'hd9;//预充电周期控制
  20. parameter Set_precharge_1 = 8'hf1;//预充电15clk 放电1clk
  21. parameter Set_normal = 8'ha6;//正常显示
  22. parameter Set_inverse = 8'ha7;//反转显示
  23. //状态机参数定义
  24. localparam S0 = 5'd0;
  25. localparam S1 = 5'd1;
  26. localparam S2 = 5'd2;
  27. localparam S3 = 5'd3;
  28. localparam S4 = 5'd4;
  29. localparam S5 = 5'd5;
  30. localparam S6 = 5'd6;
  31. localparam S7 = 5'd7;
  32. localparam S8 = 5'd8;
  33. localparam S9 = 5'd9;
  34. localparam S10 = 5'd10;
  35. localparam S11 = 5'd11;
  36. //状态寄存器
  37. reg [4:0] cstate,nstate;
  38. assign DC = 0;//发送恒为命令
  39. assign initial_done = (cstate==S11)?1:0;//初始化完成
  40. assign SPI_send = (cstate==S11)?0:1;//通过SPI发送数据
  41. //状态转移同步逻辑
  42. always @(posedge clk or negedge rst_n) begin
  43. if(!rst_n)begin
  44. cstate <= S0;
  45. end
  46. else if(SPI_done)begin
  47. cstate <= nstate;
  48. end
  49. else begin
  50. cstate <= cstate;
  51. end
  52. end
  53. //产生下一个状态组合逻辑
  54. always @(*) begin
  55. case(cstate)
  56. S0:nstate = S1;
  57. S1:nstate = S2;
  58. S2:nstate = S3;
  59. S3:nstate = S4;
  60. S4:nstate = S5;
  61. S5:nstate = S6;
  62. S6:nstate = S7;
  63. S7:nstate = S8;
  64. S8:nstate = S9;
  65. S9:nstate = S10;
  66. S10:nstate= S11;
  67. S11:nstate= S11;
  68. default:nstate = S0;
  69. endcase
  70. end
  71. //产生输出组合逻辑
  72. always @(*) begin
  73. case(cstate)
  74. S0:SPI_data = Display_off;
  75. S1:SPI_data = Set_display_clk_0;
  76. S2:SPI_data = Set_display_clk_1;
  77. S3:SPI_data = Set_charge_pump_0;
  78. S4:SPI_data = Set_charge_pump_1;
  79. S5:SPI_data = Set_contrast_0;
  80. S6:SPI_data = Set_contrast_1;
  81. S7:SPI_data = Set_precharge_0;
  82. S8:SPI_data = Set_precharge_1;
  83. S9:SPI_data = Set_inverse;
  84. S10:SPI_data= Display_on;
  85. S11:SPI_data= 0;
  86. default:SPI_data= 0;
  87. endcase
  88. end
  89. endmodule

2、清屏

        需要定义x_tmp和y_tmp计数器来遍历所有PAGE和SEG选中的一共8*128个Byte发送8'h00。

        发送数据的顺序是先发送PAGE,再发送列高地址然后列低地址,最后发送这一个位置的数据。

  1. module OLED_clear(
  2. input clk,
  3. input rst_n,
  4. input clear_en,//清零使能信号
  5. input SPI_done,//SPI发送完成通知
  6. output DC,//1数据 0命令
  7. output clear_done,//清零完成信号
  8. output reg SPI_send,//通过SPI发送数据
  9. output reg [7:0]SPI_data//SPI发送数据
  10. );
  11. //状态机状态编码
  12. localparam S0 = 3'd0;
  13. localparam S1 = 3'd1;
  14. localparam S2 = 3'd2;
  15. localparam S3 = 3'd3;
  16. localparam S4 = 3'd4;
  17. localparam S5 = 3'd5;
  18. localparam S6 = 3'd6;
  19. //状态寄存器定义
  20. reg [2:0] cstate,nstate;
  21. //内部寄存器和信号线声明
  22. reg [7:0] x_tmp,y_tmp;
  23. wire [7:0] Set_pos_0,Set_pos_1,Set_pos_2;
  24. assign Set_pos_0 = 8'hb0 | y_tmp;//PAGE地址
  25. assign Set_pos_1 = (x_tmp[7:4] & 4'hf) | 8'h10;//高位列地址
  26. assign Set_pos_2 = (x_tmp[3:0] & 4'hf);//低位列地址
  27. assign DC = (cstate == S4)?1:0;
  28. assign clear_done = (cstate == S6)?1:0;
  29. always @(posedge clk or negedge rst_n) begin
  30. if(!rst_n)begin
  31. x_tmp <= 8'd0;
  32. y_tmp <= 8'd0;
  33. end
  34. else begin
  35. case (cstate)
  36. S0:begin
  37. x_tmp <= 8'd0;
  38. y_tmp <= 8'd0;
  39. end
  40. S5:begin
  41. if(x_tmp == 130)begin
  42. x_tmp <= 8'd0;
  43. y_tmp <= y_tmp + 8'd1;
  44. end
  45. else begin
  46. x_tmp <= x_tmp + 8'd1;
  47. y_tmp <= y_tmp;
  48. end
  49. end
  50. default:begin
  51. x_tmp <= x_tmp;
  52. y_tmp <= y_tmp;
  53. end
  54. endcase
  55. end
  56. end
  57. //状态转移同步逻辑
  58. always @(posedge clk or negedge rst_n) begin
  59. if(!rst_n)begin
  60. cstate <= S0;
  61. end
  62. else begin
  63. case (cstate)
  64. S1,
  65. S2,
  66. S3,
  67. S4:cstate <= SPI_done?nstate:cstate;
  68. default:cstate <= nstate;
  69. endcase
  70. end
  71. end
  72. //产生下一个状态组合逻辑
  73. always @(*) begin
  74. nstate = cstate;
  75. case(cstate)
  76. S0:nstate = clear_en?S1:S0;
  77. S1:nstate = S2;
  78. S2:nstate = S3;
  79. S3:nstate = S4;
  80. S4:nstate = S5;
  81. S5:nstate = (x_tmp==127 && y_tmp==7)?S6:S1;
  82. S6:nstate = S0;
  83. default:nstate = S0;
  84. endcase
  85. end
  86. //产生输出组合逻辑
  87. always @(*) begin
  88. if(!rst_n)begin
  89. SPI_data = 0;
  90. SPI_send = 0;
  91. end
  92. else begin
  93. case(cstate)
  94. S1:begin
  95. SPI_data = Set_pos_0;
  96. SPI_send = 1;
  97. end
  98. S2:begin
  99. SPI_data = Set_pos_1;
  100. SPI_send = 1;
  101. end
  102. S3:begin
  103. SPI_data = Set_pos_2;
  104. SPI_send = 1;
  105. end
  106. S4:begin
  107. SPI_data = 0;
  108. SPI_send = 1;
  109. end
  110. default:begin
  111. SPI_data = 0;
  112. SPI_send = 0;
  113. end
  114. endcase
  115. end
  116. end
  117. endmodule

3、数据

        这里要显示图片:

        需要先取模然后存放到ROM中,将取模软件得到的字模使用coe文件初始化ROM:

  1. ; This .COE file specifies the contents for a block memory of depth=64, and width=128.
  2. memory_initialization_radix=16;
  3. memory_initialization_vector=
  4. 0000000000000000,0000000000000000,
  5. 0000000000000000,0000000000000000,
  6. 0000000000000000,000000001E1E3E3E,
  7. 7CFCF8F0E08080E0,F8F8FC7E3E1F1F1F,
  8. 1F1F3E3E7EFCF8F0,E080000000000000,
  9. 000000001E3E3E7E,FCFCF8F0E0000000,
  10. 0000000000000000,0000000000000000,
  11. 0000000000000000,0000000000000000,
  12. 0000000000000000,0000000000000000,
  13. 0000000000000000,0000000000000000,
  14. 00003CFCFCFCF0C0,8000000000000080,
  15. C0F3FFFFFF3F3FFF,FFFFF1C080000000,
  16. 0000000000030707,07077CFCFCFCF0C0,
  17. 8000000000000080,C0FFFFFFFF3F0000,
  18. 0000000000000000,0000000000000000,
  19. 0000000000000000,0000000000000000,
  20. 0000000000000000,0000000000000000,
  21. 0000000000000000,0000000000000000,
  22. 000000000103070F,0F0F1FDFDFDFCFCF,
  23. 8F87030100000000,0307070F0F0F1FDF,
  24. E0E0E0C0C0800000,000000010387C7CF,
  25. CFFFFFFFFFFFCFCF,8F87030100000000,
  26. 0000000000000000,0000000000000000,
  27. 0000000000000000,0000000000000000,
  28. 0000000000000000,0000000000000000,
  29. 0000000000000000,0000000000000000,
  30. 0000808080800000,000000030307070F,
  31. 1FFFFFFEF8E08080,8080000000000001,
  32. 030303070FFFFFFE,FCF0F8FEFFFF1F0F,
  33. 070303030303070F,1FFFFFFEF8000000,
  34. 0000000000000000,0000000000000000,
  35. 0000000000000000,0000000000000000,
  36. 0000000000000000,0000000000000000,
  37. 0000000000000000,0000000000000000,
  38. 00000F3F7FFFFEF8,F0E0E0C0C0E0E0F0,
  39. F8FFFF7F1F070F1F,3F7FFCF8F0F0E0E0,
  40. E0E0F0F8FCFF7F3F,0F030F3F7FFFFCF8,
  41. F0E0E0E000000000,0000000000000000
  42. 0000000000000000,0000000000000000,
  43. 0000000000000000,0000000000000000,
  44. 0000000000000000,0000000000000000,
  45. 0000000000000000,0000000000000000,
  46. 00000080C0E0F1F1,FBFB7B7B03030303,
  47. 0100000000000000,C0E0E0F1F1F9F9F9,
  48. F9F9F9F1F0E0E0C0,00000080C0E0F0F1,
  49. F9F97B7B00000000,0000000000000000,
  50. 0000000000000000,0000000000000000,
  51. 0000000000000000,0000000000000000,
  52. 0000000000000000,0000000000000000,
  53. 0000000000000000,0000000000000000,
  54. 0000FEFFFFFFC701,0000000000000000,
  55. 00C0F0F0F0E0FCFF,FFFFDF0301000000,
  56. 00000001031F3F3F,3F3CFEFFFFFF8701,
  57. 0000000000000000,00E0F0F0F0E00000,
  58. 0000000000000000,0000000000000000,
  59. 0000000000000000,0000000000000000,
  60. 0000000000000000,0000000000000000,
  61. 0000000000000000,0000000000000000,
  62. 000001070F1F3F3F,7E7C7C7C7C7C7C7E,
  63. 3F3F1F0F07010003,0F1F3F3F7C7C7878,
  64. 3000000000000000,000001070F1F3F3F,
  65. 7E7C7C7C7C7C7C7E,3F1F1F0F03000000,
  66. 0000000000000000,0000000000000000,
  67. 0000000000000000,0000000000000000;

        例化一个 ROM的IP,配置如下:

         将coe文件添加并初始化:

         数据发送模块,每次从ROM中读取64位数据分8次发送:

  1. module OLED_write_data(
  2. input clk,
  3. input rst_n,
  4. input write_en,
  5. input SPI_done,
  6. input [63:0]write_data,//需要发送的数据
  7. input [6:0]set_pos_x,
  8. input [2:0]set_pos_y,
  9. output DC,
  10. output write_done,//写数据完成标志
  11. output reg SPI_send,//SPI传输使能
  12. output reg [7:0] SPI_data//需要SPI发送的字节数据
  13. );
  14. //状态机状态编码
  15. localparam IDLE = 3'd0;//空闲状态
  16. localparam POS0 = 3'd1;//设置页地址
  17. localparam POS1 = 3'd2;//设置列高地址
  18. localparam POS2 = 3'd3;//设置列低地址
  19. localparam DATA = 3'd4;//发送对应的数据
  20. localparam JUDGE= 3'd5;//判断是否发送完成
  21. localparam STOP = 3'd6;//停止发送
  22. //状态寄存器
  23. reg [2:0] cstate,nstate;
  24. //内部寄存器和信号线声明
  25. reg [2:0] count;//发送循环数计数器
  26. reg [63:0] write_data_reg;//暂存需要发送的数据
  27. reg [7:0] x_tmp,y_tmp;
  28. wire [7:0] Set_pos_0,Set_pos_1,Set_pos_2;
  29. assign Set_pos_0 = 8'hb0 | y_tmp; //页地址
  30. assign Set_pos_1 = (x_tmp[7:4] & 4'hf) | 8'h10;//高位列地址
  31. assign Set_pos_2 = (x_tmp[3:0] & 4'hf); //低位列地址
  32. assign DC = (cstate == DATA)?1:0;
  33. assign write_done = (cstate == STOP)?1:0;
  34. always @(posedge clk or negedge rst_n) begin
  35. if(!rst_n)begin
  36. x_tmp <= 8'd0;
  37. y_tmp <= 8'd0;
  38. write_data_reg <= 0;
  39. count <= 0;
  40. end
  41. else begin
  42. case (cstate)
  43. IDLE:begin
  44. x_tmp <= {1'b0,set_pos_x};
  45. y_tmp <= {5'd0,set_pos_y};
  46. write_data_reg <= write_data;
  47. count <= 0;
  48. end
  49. JUDGE:begin
  50. x_tmp <= x_tmp + 8'd1;
  51. // y_tmp <= y_tmp;
  52. // if(x_tmp>122) y_tmp<=y_tmp+1;
  53. write_data_reg <= (write_data_reg<<8);
  54. count <= count + 1;
  55. end
  56. default:begin
  57. x_tmp <= x_tmp;
  58. y_tmp <= y_tmp;
  59. write_data_reg <= write_data_reg;
  60. count <= count;
  61. end
  62. endcase
  63. end
  64. end
  65. //状态转移同步逻辑
  66. always @(posedge clk or negedge rst_n) begin
  67. if(!rst_n)begin
  68. cstate <= IDLE;
  69. end
  70. else begin
  71. case (cstate)
  72. POS0,
  73. POS1,
  74. POS2,
  75. DATA:cstate <= SPI_done?nstate:cstate;
  76. default:cstate <= nstate;
  77. endcase
  78. end
  79. end
  80. //产生下一个状态组合逻辑
  81. always @(*) begin
  82. case(cstate)
  83. IDLE:nstate = write_en?POS0:IDLE;
  84. POS0:nstate = POS1;
  85. POS1:nstate = POS2;
  86. POS2:nstate = DATA;
  87. DATA:nstate = JUDGE;
  88. JUDGE:nstate = (&count)?STOP:POS0;
  89. STOP:nstate = IDLE;
  90. default:nstate = IDLE;
  91. endcase
  92. end
  93. //产生输出组合逻辑
  94. always @(*)begin
  95. if(!rst_n)begin
  96. SPI_data = 0;
  97. SPI_send = 0;
  98. end
  99. else begin
  100. case(cstate)
  101. IDLE:begin
  102. SPI_data = 0;
  103. SPI_send = 0;
  104. end
  105. POS0:begin
  106. SPI_data = Set_pos_0;
  107. SPI_send = 1;
  108. end
  109. POS1:begin
  110. SPI_data = Set_pos_1;
  111. SPI_send = 1;
  112. end
  113. POS2:begin
  114. SPI_data = Set_pos_2;
  115. SPI_send = 1;
  116. end
  117. DATA:begin
  118. SPI_data = write_data_reg[63:56];
  119. SPI_send = 1;
  120. end
  121. JUDGE:begin
  122. SPI_data = SPI_data;
  123. SPI_send = 0;
  124. end
  125. STOP:begin
  126. SPI_data = SPI_data;
  127. SPI_send = SPI_send;
  128. end
  129. default:begin
  130. SPI_data = 0;
  131. SPI_send = 0;
  132. end
  133. endcase
  134. end
  135. end
  136. endmodule

四、top源码

        由于需要发送8*128=1024个Byte的数据,而发送数据模块一次从ROM中读取1*8个Byte,因此需要读取ROM128次,这就需要128个读数据状态和一个初始化状态、一个清屏状态和一个停止发送状态,使用格雷码来编码状态机并使用脚本来生成top代码。

  1. module top(
  2. input sys_clk,//系统时钟 100MHz
  3. input sys_rst_n,//系统复位
  4. output sclk,//同步时钟
  5. output sck,
  6. output reg res=0,//OLED清屏信号 低电平有效
  7. output MOSI,//主机输出 从机输入
  8. output CS,//片选信号 低电平有效
  9. output DC//1数据 0命令
  10. );
  11. //状态编码
  12. localparam INIT= 9'b000000000;//初始化
  13. localparam CLR = 9'b000000001;//清屏
  14. localparam D0 = 9'b000000011;//发送数据周期
  15. localparam D1 = 9'b000000010;
  16. localparam D2 = 9'b000000110;
  17. localparam D3 = 9'b000000111;
  18. localparam D4 = 9'b000000101;
  19. localparam D5 = 9'b000000100;
  20. localparam D6 = 9'b000001100;
  21. localparam D7 = 9'b000001101;
  22. localparam D8 = 9'b000001111;
  23. localparam D9 = 9'b000001110;
  24. localparam D10 = 9'b000001010;
  25. localparam D11 = 9'b000001011;
  26. localparam D12 = 9'b000001001;
  27. localparam D13 = 9'b000001000;
  28. localparam D14 = 9'b000011000;
  29. localparam D15 = 9'b000011001;
  30. localparam D16 = 9'b000011011;
  31. localparam D17 = 9'b000011010;
  32. localparam D18 = 9'b000011110;
  33. localparam D19 = 9'b000011111;
  34. localparam D20 = 9'b000011101;
  35. localparam D21 = 9'b000011100;
  36. localparam D22 = 9'b000010100;
  37. localparam D23 = 9'b000010101;
  38. localparam D24 = 9'b000010111;
  39. localparam D25 = 9'b000010110;
  40. localparam D26 = 9'b000010010;
  41. localparam D27 = 9'b000010011;
  42. localparam D28 = 9'b000010001;
  43. localparam D29 = 9'b000010000;
  44. localparam D30 = 9'b000110000;
  45. localparam D31 = 9'b000110001;
  46. localparam D32 = 9'b000110011;
  47. localparam D33 = 9'b000110010;
  48. localparam D34 = 9'b000110110;
  49. localparam D35 = 9'b000110111;
  50. localparam D36 = 9'b000110101;
  51. localparam D37 = 9'b000110100;
  52. localparam D38 = 9'b000111100;
  53. localparam D39 = 9'b000111101;
  54. localparam D40 = 9'b000111111;
  55. localparam D41 = 9'b000111110;
  56. localparam D42 = 9'b000111010;
  57. localparam D43 = 9'b000111011;
  58. localparam D44 = 9'b000111001;
  59. localparam D45 = 9'b000111000;
  60. localparam D46 = 9'b000101000;
  61. localparam D47 = 9'b000101001;
  62. localparam D48 = 9'b000101011;
  63. localparam D49 = 9'b000101010;
  64. localparam D50 = 9'b000101110;
  65. localparam D51 = 9'b000101111;
  66. localparam D52 = 9'b000101101;
  67. localparam D53 = 9'b000101100;
  68. localparam D54 = 9'b000100100;
  69. localparam D55 = 9'b000100101;
  70. localparam D56 = 9'b000100111;
  71. localparam D57 = 9'b000100110;
  72. localparam D58 = 9'b000100010;
  73. localparam D59 = 9'b000100011;
  74. localparam D60 = 9'b000100001;
  75. localparam D61 = 9'b000100000;
  76. localparam D62 = 9'b001100000;
  77. localparam D63 = 9'b001100001;
  78. localparam D64 = 9'b001100011;
  79. localparam D65 = 9'b001100010;
  80. localparam D66 = 9'b001100110;
  81. localparam D67 = 9'b001100111;
  82. localparam D68 = 9'b001100101;
  83. localparam D69 = 9'b001100100;
  84. localparam D70 = 9'b001101100;
  85. localparam D71 = 9'b001101101;
  86. localparam D72 = 9'b001101111;
  87. localparam D73 = 9'b001101110;
  88. localparam D74 = 9'b001101010;
  89. localparam D75 = 9'b001101011;
  90. localparam D76 = 9'b001101001;
  91. localparam D77 = 9'b001101000;
  92. localparam D78 = 9'b001111000;
  93. localparam D79 = 9'b001111001;
  94. localparam D80 = 9'b001111011;
  95. localparam D81 = 9'b001111010;
  96. localparam D82 = 9'b001111110;
  97. localparam D83 = 9'b001111111;
  98. localparam D84 = 9'b001111101;
  99. localparam D85 = 9'b001111100;
  100. localparam D86 = 9'b001110100;
  101. localparam D87 = 9'b001110101;
  102. localparam D88 = 9'b001110111;
  103. localparam D89 = 9'b001110110;
  104. localparam D90 = 9'b001110010;
  105. localparam D91 = 9'b001110011;
  106. localparam D92 = 9'b001110001;
  107. localparam D93 = 9'b001110000;
  108. localparam D94 = 9'b001010000;
  109. localparam D95 = 9'b001010001;
  110. localparam D96 = 9'b001010011;
  111. localparam D97 = 9'b001010010;
  112. localparam D98 = 9'b001010110;
  113. localparam D99 = 9'b001010111;
  114. localparam D100 = 9'b001010101;
  115. localparam D101 = 9'b001010100;
  116. localparam D102 = 9'b001011100;
  117. localparam D103 = 9'b001011101;
  118. localparam D104 = 9'b001011111;
  119. localparam D105 = 9'b001011110;
  120. localparam D106 = 9'b001011010;
  121. localparam D107 = 9'b001011011;
  122. localparam D108 = 9'b001011001;
  123. localparam D109 = 9'b001011000;
  124. localparam D110 = 9'b001001000;
  125. localparam D111 = 9'b001001001;
  126. localparam D112 = 9'b001001011;
  127. localparam D113 = 9'b001001010;
  128. localparam D114 = 9'b001001110;
  129. localparam D115 = 9'b001001111;
  130. localparam D116 = 9'b001001101;
  131. localparam D117 = 9'b001001100;
  132. localparam D118 = 9'b001000100;
  133. localparam D119 = 9'b001000101;
  134. localparam D120 = 9'b001000111;
  135. localparam D121 = 9'b001000110;
  136. localparam D122 = 9'b001000010;
  137. localparam D123 = 9'b001000011;
  138. localparam D124 = 9'b001000001;
  139. localparam D125 = 9'b001000000;
  140. localparam D126 = 9'b011000000;
  141. localparam D127 = 9'b011000001;
  142. localparam STOP = 9'b011000011;//发送结束
  143. //从ROM中读取需要发送的数据
  144. reg [6:0]ROM_addr=0;//ROM访问地址
  145. wire [63:0]ROM_data;//ROM输出数据
  146. blk_mem_gen_0 rom(
  147. .clka(sys_clk), // input wire clka
  148. .addra(ROM_addr), // input wire [6 : 0] addra
  149. .douta(ROM_data) // output wire [63 : 0] douta
  150. );
  151. //状泰寄存器
  152. reg [8:0] cstate,nstate=0;
  153. reg [31:0]reset_cnt=0;//复位控制计数�??
  154. reg rst_n=0;
  155. //上电复位逻辑
  156. always @(posedge sys_clk) begin
  157. if(reset_cnt >= 30000)
  158. reset_cnt <= 30000;
  159. else
  160. reset_cnt <= reset_cnt + 1;
  161. end
  162. always @(posedge sys_clk) begin
  163. if(reset_cnt == 10)begin
  164. res <= 1;
  165. rst_n <= 1;
  166. end
  167. else if(reset_cnt == 10000)begin
  168. res <= 0;
  169. rst_n <= 0;
  170. end
  171. else if(reset_cnt == 20000)begin
  172. res <= 1;
  173. rst_n <= rst_n;
  174. end
  175. else if(reset_cnt == 30000)begin
  176. res <= res;
  177. rst_n <= 1;
  178. end
  179. else begin
  180. res <= res;
  181. rst_n <= rst_n;
  182. end
  183. end
  184. //SPI主机例化
  185. reg SPI_send=0;//SPI发�?�使能信�??
  186. reg [7:0] SPI_data=0;//SPI�??要发送的字节数据
  187. wire SPI_done;//SPI发�?�完成标�??
  188. reg DC_in=0;//数据/命令控制�??
  189. SPI_Master SPI_Master_(
  190. .sys_clk (sys_clk),
  191. .rst_n(1'b1),
  192. .SPI_send (SPI_send),
  193. .SPI_data (SPI_data),
  194. .DC_in (DC_in),
  195. .DC_out (DC),
  196. .sclk (sclk),
  197. .MOSI (MOSI),
  198. .CS (CS),
  199. .SPI_done (SPI_done),
  200. .sck (sck)
  201. );
  202. //OLED初始化模块实例化
  203. wire SPI_send_init;
  204. wire DC_init;
  205. wire [7:0] SPI_data_init;
  206. wire initial_done;
  207. OLED_initial OLED_initial_(
  208. .clk (sclk),
  209. .rst_n (rst_n),
  210. .SPI_done (SPI_done),
  211. .DC (DC_init),
  212. .initial_done (initial_done),
  213. .SPI_send (SPI_send_init),
  214. .SPI_data (SPI_data_init)
  215. );
  216. //OLED写信号模块实例化,讲输入的64位向量拆分发送
  217. reg [6:0]set_pos_x=0;//列的索引 0->127
  218. reg [2:0]set_pos_y=0;//PAGE的索引 0->7
  219. wire write_en;
  220. wire DC_write;
  221. wire write_done;
  222. reg [63:0]write_data=0;
  223. wire SPI_send_write;
  224. wire [7:0] SPI_data_write;
  225. assign write_en = (cstate==INIT || cstate == CLR || cstate == STOP)?0:1;
  226. OLED_write_data OLED_write_(
  227. .clk (sclk),
  228. .rst_n (rst_n),
  229. .write_en (write_en),
  230. .SPI_done (SPI_done),
  231. .write_data (write_data),
  232. .set_pos_x (set_pos_x),
  233. .set_pos_y (set_pos_y),
  234. .DC (DC_write),
  235. .write_done (write_done),
  236. .SPI_send (SPI_send_write),
  237. .SPI_data (SPI_data_write)
  238. );
  239. //OLED清屏模块实例化
  240. wire clear_en;
  241. wire DC_clear;
  242. wire clear_done;
  243. wire SPI_send_clear;
  244. wire [7:0]SPI_data_clear;
  245. assign clear_en = (cstate==CLR)?1:0;
  246. OLED_clear OLED_clear_(
  247. .clk (sclk),
  248. .rst_n (rst_n),
  249. .clear_en (clear_en),
  250. .SPI_done (SPI_done),
  251. .DC (DC_clear),
  252. .clear_done (clear_done),
  253. .SPI_send (SPI_send_clear),
  254. .SPI_data (SPI_data_clear)
  255. );
  256. //状态转移同步逻辑
  257. always @(posedge sclk) begin
  258. if(!rst_n)begin
  259. cstate <= INIT;
  260. end
  261. else begin
  262. cstate <= nstate;
  263. end
  264. end
  265. //产生下一个状态组合逻辑
  266. always @(*) begin
  267. case(cstate)
  268. INIT:nstate = initial_done?CLR:INIT;
  269. CLR :nstate = clear_done?D0:CLR;
  270. D0:nstate = write_done?D1:D0;
  271. D1:nstate = write_done?D2:D1;
  272. D2:nstate = write_done?D3:D2;
  273. D3:nstate = write_done?D4:D3;
  274. D4:nstate = write_done?D5:D4;
  275. D5:nstate = write_done?D6:D5;
  276. D6:nstate = write_done?D7:D6;
  277. D7:nstate = write_done?D8:D7;
  278. D8:nstate = write_done?D9:D8;
  279. D9:nstate = write_done?D10:D9;
  280. D10:nstate = write_done?D11:D10;
  281. D11:nstate = write_done?D12:D11;
  282. D12:nstate = write_done?D13:D12;
  283. D13:nstate = write_done?D14:D13;
  284. D14:nstate = write_done?D15:D14;
  285. D15:nstate = write_done?D16:D15;
  286. D16:nstate = write_done?D17:D16;
  287. D17:nstate = write_done?D18:D17;
  288. D18:nstate = write_done?D19:D18;
  289. D19:nstate = write_done?D20:D19;
  290. D20:nstate = write_done?D21:D20;
  291. D21:nstate = write_done?D22:D21;
  292. D22:nstate = write_done?D23:D22;
  293. D23:nstate = write_done?D24:D23;
  294. D24:nstate = write_done?D25:D24;
  295. D25:nstate = write_done?D26:D25;
  296. D26:nstate = write_done?D27:D26;
  297. D27:nstate = write_done?D28:D27;
  298. D28:nstate = write_done?D29:D28;
  299. D29:nstate = write_done?D30:D29;
  300. D30:nstate = write_done?D31:D30;
  301. D31:nstate = write_done?D32:D31;
  302. D32:nstate = write_done?D33:D32;
  303. D33:nstate = write_done?D34:D33;
  304. D34:nstate = write_done?D35:D34;
  305. D35:nstate = write_done?D36:D35;
  306. D36:nstate = write_done?D37:D36;
  307. D37:nstate = write_done?D38:D37;
  308. D38:nstate = write_done?D39:D38;
  309. D39:nstate = write_done?D40:D39;
  310. D40:nstate = write_done?D41:D40;
  311. D41:nstate = write_done?D42:D41;
  312. D42:nstate = write_done?D43:D42;
  313. D43:nstate = write_done?D44:D43;
  314. D44:nstate = write_done?D45:D44;
  315. D45:nstate = write_done?D46:D45;
  316. D46:nstate = write_done?D47:D46;
  317. D47:nstate = write_done?D48:D47;
  318. D48:nstate = write_done?D49:D48;
  319. D49:nstate = write_done?D50:D49;
  320. D50:nstate = write_done?D51:D50;
  321. D51:nstate = write_done?D52:D51;
  322. D52:nstate = write_done?D53:D52;
  323. D53:nstate = write_done?D54:D53;
  324. D54:nstate = write_done?D55:D54;
  325. D55:nstate = write_done?D56:D55;
  326. D56:nstate = write_done?D57:D56;
  327. D57:nstate = write_done?D58:D57;
  328. D58:nstate = write_done?D59:D58;
  329. D59:nstate = write_done?D60:D59;
  330. D60:nstate = write_done?D61:D60;
  331. D61:nstate = write_done?D62:D61;
  332. D62:nstate = write_done?D63:D62;
  333. D63:nstate = write_done?D64:D63;
  334. D64:nstate = write_done?D65:D64;
  335. D65:nstate = write_done?D66:D65;
  336. D66:nstate = write_done?D67:D66;
  337. D67:nstate = write_done?D68:D67;
  338. D68:nstate = write_done?D69:D68;
  339. D69:nstate = write_done?D70:D69;
  340. D70:nstate = write_done?D71:D70;
  341. D71:nstate = write_done?D72:D71;
  342. D72:nstate = write_done?D73:D72;
  343. D73:nstate = write_done?D74:D73;
  344. D74:nstate = write_done?D75:D74;
  345. D75:nstate = write_done?D76:D75;
  346. D76:nstate = write_done?D77:D76;
  347. D77:nstate = write_done?D78:D77;
  348. D78:nstate = write_done?D79:D78;
  349. D79:nstate = write_done?D80:D79;
  350. D80:nstate = write_done?D81:D80;
  351. D81:nstate = write_done?D82:D81;
  352. D82:nstate = write_done?D83:D82;
  353. D83:nstate = write_done?D84:D83;
  354. D84:nstate = write_done?D85:D84;
  355. D85:nstate = write_done?D86:D85;
  356. D86:nstate = write_done?D87:D86;
  357. D87:nstate = write_done?D88:D87;
  358. D88:nstate = write_done?D89:D88;
  359. D89:nstate = write_done?D90:D89;
  360. D90:nstate = write_done?D91:D90;
  361. D91:nstate = write_done?D92:D91;
  362. D92:nstate = write_done?D93:D92;
  363. D93:nstate = write_done?D94:D93;
  364. D94:nstate = write_done?D95:D94;
  365. D95:nstate = write_done?D96:D95;
  366. D96:nstate = write_done?D97:D96;
  367. D97:nstate = write_done?D98:D97;
  368. D98:nstate = write_done?D99:D98;
  369. D99:nstate = write_done?D100:D99;
  370. D100:nstate = write_done?D101:D100;
  371. D101:nstate = write_done?D102:D101;
  372. D102:nstate = write_done?D103:D102;
  373. D103:nstate = write_done?D104:D103;
  374. D104:nstate = write_done?D105:D104;
  375. D105:nstate = write_done?D106:D105;
  376. D106:nstate = write_done?D107:D106;
  377. D107:nstate = write_done?D108:D107;
  378. D108:nstate = write_done?D109:D108;
  379. D109:nstate = write_done?D110:D109;
  380. D110:nstate = write_done?D111:D110;
  381. D111:nstate = write_done?D112:D111;
  382. D112:nstate = write_done?D113:D112;
  383. D113:nstate = write_done?D114:D113;
  384. D114:nstate = write_done?D115:D114;
  385. D115:nstate = write_done?D116:D115;
  386. D116:nstate = write_done?D117:D116;
  387. D117:nstate = write_done?D118:D117;
  388. D118:nstate = write_done?D119:D118;
  389. D119:nstate = write_done?D120:D119;
  390. D120:nstate = write_done?D121:D120;
  391. D121:nstate = write_done?D122:D121;
  392. D122:nstate = write_done?D123:D122;
  393. D123:nstate = write_done?D124:D123;
  394. D124:nstate = write_done?D125:D124;
  395. D125:nstate = write_done?D126:D125;
  396. D126:nstate = write_done?D127:D126;
  397. D127:nstate = write_done?STOP:D127;
  398. STOP:nstate = sys_rst_n?STOP:INIT;
  399. default:nstate = INIT;
  400. endcase
  401. end
  402. //根据状态提供相应的输出
  403. wire PAGE_inc_flag = (&set_pos_x)?1:0;
  404. always @(*) begin
  405. if(!rst_n)begin
  406. set_pos_x = 0;
  407. set_pos_y = 0;
  408. write_data= 64'd0;
  409. end
  410. else begin
  411. case (cstate)
  412. //PAGE0
  413. D0:begin
  414. set_pos_x = 0;
  415. set_pos_y = 0;
  416. write_data = ROM_data;
  417. ROM_addr = 0;
  418. end
  419. D1:begin
  420. set_pos_x = 8;
  421. set_pos_y = 0;
  422. write_data = ROM_data;
  423. ROM_addr = 1;
  424. end
  425. D2:begin
  426. set_pos_x = 16;
  427. set_pos_y = 0;
  428. write_data = ROM_data;
  429. ROM_addr = 2;
  430. end
  431. D3:begin
  432. set_pos_x = 24;
  433. set_pos_y = 0;
  434. write_data = ROM_data;
  435. ROM_addr = 3;
  436. end
  437. D4:begin
  438. set_pos_x = 32;
  439. set_pos_y = 0;
  440. write_data = ROM_data;
  441. ROM_addr = 4;
  442. end
  443. D5:begin
  444. set_pos_x = 40;
  445. set_pos_y = 0;
  446. write_data = ROM_data;
  447. ROM_addr = 5;
  448. end
  449. D6:begin
  450. set_pos_x = 48;
  451. set_pos_y = 0;
  452. write_data = ROM_data;
  453. ROM_addr = 6;
  454. end
  455. D7:begin
  456. set_pos_x = 56;
  457. set_pos_y = 0;
  458. write_data = ROM_data;
  459. ROM_addr = 7;
  460. end
  461. D8:begin
  462. set_pos_x = 64;
  463. set_pos_y = 0;
  464. write_data = ROM_data;
  465. ROM_addr = 8;
  466. end
  467. D9:begin
  468. set_pos_x = 72;
  469. set_pos_y = 0;
  470. write_data = ROM_data;
  471. ROM_addr = 9;
  472. end
  473. D10:begin
  474. set_pos_x = 80;
  475. set_pos_y = 0;
  476. write_data = ROM_data;
  477. ROM_addr = 10;
  478. end
  479. D11:begin
  480. set_pos_x = 88;
  481. set_pos_y = 0;
  482. write_data = ROM_data;
  483. ROM_addr = 11;
  484. end
  485. D12:begin
  486. set_pos_x = 96;
  487. set_pos_y = 0;
  488. write_data = ROM_data;
  489. ROM_addr = 12;
  490. end
  491. D13:begin
  492. set_pos_x = 104;
  493. set_pos_y = 0;
  494. write_data = ROM_data;
  495. ROM_addr = 13;
  496. end
  497. D14:begin
  498. set_pos_x = 112;
  499. set_pos_y = 0;
  500. write_data = ROM_data;
  501. ROM_addr = 14;
  502. end
  503. D15:begin
  504. set_pos_x = 120;
  505. set_pos_y = 0;
  506. write_data = ROM_data;
  507. ROM_addr = 15;
  508. end
  509. //PAGE1
  510. D16:begin
  511. set_pos_x = 0;
  512. set_pos_y = 1;
  513. write_data = ROM_data;
  514. ROM_addr = 16;
  515. end
  516. D17:begin
  517. set_pos_x = 8;
  518. set_pos_y = 1;
  519. write_data = ROM_data;
  520. ROM_addr = 17;
  521. end
  522. D18:begin
  523. set_pos_x = 16;
  524. set_pos_y = 1;
  525. write_data = ROM_data;
  526. ROM_addr = 18;
  527. end
  528. D19:begin
  529. set_pos_x = 24;
  530. set_pos_y = 1;
  531. write_data = ROM_data;
  532. ROM_addr = 19;
  533. end
  534. D20:begin
  535. set_pos_x = 32;
  536. set_pos_y = 1;
  537. write_data = ROM_data;
  538. ROM_addr = 20;
  539. end
  540. D21:begin
  541. set_pos_x = 40;
  542. set_pos_y = 1;
  543. write_data = ROM_data;
  544. ROM_addr = 21;
  545. end
  546. D22:begin
  547. set_pos_x = 48;
  548. set_pos_y = 1;
  549. write_data = ROM_data;
  550. ROM_addr = 22;
  551. end
  552. D23:begin
  553. set_pos_x = 56;
  554. set_pos_y = 1;
  555. write_data = ROM_data;
  556. ROM_addr = 23;
  557. end
  558. D24:begin
  559. set_pos_x = 64;
  560. set_pos_y = 1;
  561. write_data = ROM_data;
  562. ROM_addr = 24;
  563. end
  564. D25:begin
  565. set_pos_x = 72;
  566. set_pos_y = 1;
  567. write_data = ROM_data;
  568. ROM_addr = 25;
  569. end
  570. D26:begin
  571. set_pos_x = 80;
  572. set_pos_y = 1;
  573. write_data = ROM_data;
  574. ROM_addr = 26;
  575. end
  576. D27:begin
  577. set_pos_x = 88;
  578. set_pos_y = 1;
  579. write_data = ROM_data;
  580. ROM_addr = 27;
  581. end
  582. D28:begin
  583. set_pos_x = 96;
  584. set_pos_y = 1;
  585. write_data = ROM_data;
  586. ROM_addr = 28;
  587. end
  588. D29:begin
  589. set_pos_x = 104;
  590. set_pos_y = 1;
  591. write_data = ROM_data;
  592. ROM_addr = 29;
  593. end
  594. D30:begin
  595. set_pos_x = 112;
  596. set_pos_y = 1;
  597. write_data = ROM_data;
  598. ROM_addr = 30;
  599. end
  600. D31:begin
  601. set_pos_x = 120;
  602. set_pos_y = 1;
  603. write_data = ROM_data;
  604. ROM_addr = 31;
  605. end
  606. //PAGE2
  607. D32:begin
  608. set_pos_x = 0;
  609. set_pos_y = 2;
  610. write_data = ROM_data;
  611. ROM_addr = 32;
  612. end
  613. D33:begin
  614. set_pos_x = 8;
  615. set_pos_y = 2;
  616. write_data = ROM_data;
  617. ROM_addr = 33;
  618. end
  619. D34:begin
  620. set_pos_x = 16;
  621. set_pos_y = 2;
  622. write_data = ROM_data;
  623. ROM_addr = 34;
  624. end
  625. D35:begin
  626. set_pos_x = 24;
  627. set_pos_y = 2;
  628. write_data = ROM_data;
  629. ROM_addr = 35;
  630. end
  631. D36:begin
  632. set_pos_x = 32;
  633. set_pos_y = 2;
  634. write_data = ROM_data;
  635. ROM_addr = 36;
  636. end
  637. D37:begin
  638. set_pos_x = 40;
  639. set_pos_y = 2;
  640. write_data = ROM_data;
  641. ROM_addr = 37;
  642. end
  643. D38:begin
  644. set_pos_x = 48;
  645. set_pos_y = 2;
  646. write_data = ROM_data;
  647. ROM_addr = 38;
  648. end
  649. D39:begin
  650. set_pos_x = 56;
  651. set_pos_y = 2;
  652. write_data = ROM_data;
  653. ROM_addr = 39;
  654. end
  655. D40:begin
  656. set_pos_x = 64;
  657. set_pos_y = 2;
  658. write_data = ROM_data;
  659. ROM_addr = 40;
  660. end
  661. D41:begin
  662. set_pos_x = 72;
  663. set_pos_y = 2;
  664. write_data = ROM_data;
  665. ROM_addr = 41;
  666. end
  667. D42:begin
  668. set_pos_x = 80;
  669. set_pos_y = 2;
  670. write_data = ROM_data;
  671. ROM_addr = 42;
  672. end
  673. D43:begin
  674. set_pos_x = 88;
  675. set_pos_y = 2;
  676. write_data = ROM_data;
  677. ROM_addr = 43;
  678. end
  679. D44:begin
  680. set_pos_x = 96;
  681. set_pos_y = 2;
  682. write_data = ROM_data;
  683. ROM_addr = 44;
  684. end
  685. D45:begin
  686. set_pos_x = 104;
  687. set_pos_y = 2;
  688. write_data = ROM_data;
  689. ROM_addr = 45;
  690. end
  691. D46:begin
  692. set_pos_x = 112;
  693. set_pos_y = 2;
  694. write_data = ROM_data;
  695. ROM_addr = 46;
  696. end
  697. D47:begin
  698. set_pos_x = 120;
  699. set_pos_y = 2;
  700. write_data = ROM_data;
  701. ROM_addr = 47;
  702. end
  703. //PAGE3
  704. D48:begin
  705. set_pos_x = 0;
  706. set_pos_y = 3;
  707. write_data = ROM_data;
  708. ROM_addr = 48;
  709. end
  710. D49:begin
  711. set_pos_x = 8;
  712. set_pos_y = 3;
  713. write_data = ROM_data;
  714. ROM_addr = 49;
  715. end
  716. D50:begin
  717. set_pos_x = 16;
  718. set_pos_y = 3;
  719. write_data = ROM_data;
  720. ROM_addr = 50;
  721. end
  722. D51:begin
  723. set_pos_x = 24;
  724. set_pos_y = 3;
  725. write_data = ROM_data;
  726. ROM_addr = 51;
  727. end
  728. D52:begin
  729. set_pos_x = 32;
  730. set_pos_y = 3;
  731. write_data = ROM_data;
  732. ROM_addr = 52;
  733. end
  734. D53:begin
  735. set_pos_x = 40;
  736. set_pos_y = 3;
  737. write_data = ROM_data;
  738. ROM_addr = 53;
  739. end
  740. D54:begin
  741. set_pos_x = 48;
  742. set_pos_y = 3;
  743. write_data = ROM_data;
  744. ROM_addr = 54;
  745. end
  746. D55:begin
  747. set_pos_x = 56;
  748. set_pos_y = 3;
  749. write_data = ROM_data;
  750. ROM_addr = 55;
  751. end
  752. D56:begin
  753. set_pos_x = 64;
  754. set_pos_y = 3;
  755. write_data = ROM_data;
  756. ROM_addr = 56;
  757. end
  758. D57:begin
  759. set_pos_x = 72;
  760. set_pos_y = 3;
  761. write_data = ROM_data;
  762. ROM_addr = 57;
  763. end
  764. D58:begin
  765. set_pos_x = 80;
  766. set_pos_y = 3;
  767. write_data = ROM_data;
  768. ROM_addr = 58;
  769. end
  770. D59:begin
  771. set_pos_x = 88;
  772. set_pos_y = 3;
  773. write_data = ROM_data;
  774. ROM_addr = 59;
  775. end
  776. D60:begin
  777. set_pos_x = 96;
  778. set_pos_y = 3;
  779. write_data = ROM_data;
  780. ROM_addr = 60;
  781. end
  782. D61:begin
  783. set_pos_x = 104;
  784. set_pos_y = 3;
  785. write_data = ROM_data;
  786. ROM_addr = 61;
  787. end
  788. D62:begin
  789. set_pos_x = 112;
  790. set_pos_y = 3;
  791. write_data = ROM_data;
  792. ROM_addr = 62;
  793. end
  794. D63:begin
  795. set_pos_x = 120;
  796. set_pos_y = 3;
  797. write_data = ROM_data;
  798. ROM_addr = 63;
  799. end
  800. //PAGE4
  801. D64:begin
  802. set_pos_x = 0;
  803. set_pos_y = 4;
  804. write_data = ROM_data;
  805. ROM_addr = 64;
  806. end
  807. D65:begin
  808. set_pos_x = 8;
  809. set_pos_y = 4;
  810. write_data = ROM_data;
  811. ROM_addr = 65;
  812. end
  813. D66:begin
  814. set_pos_x = 16;
  815. set_pos_y = 4;
  816. write_data = ROM_data;
  817. ROM_addr = 66;
  818. end
  819. D67:begin
  820. set_pos_x = 24;
  821. set_pos_y = 4;
  822. write_data = ROM_data;
  823. ROM_addr = 67;
  824. end
  825. D68:begin
  826. set_pos_x = 32;
  827. set_pos_y = 4;
  828. write_data = ROM_data;
  829. ROM_addr = 68;
  830. end
  831. D69:begin
  832. set_pos_x = 40;
  833. set_pos_y = 4;
  834. write_data = ROM_data;
  835. ROM_addr = 69;
  836. end
  837. D70:begin
  838. set_pos_x = 48;
  839. set_pos_y = 4;
  840. write_data = ROM_data;
  841. ROM_addr = 70;
  842. end
  843. D71:begin
  844. set_pos_x = 56;
  845. set_pos_y = 4;
  846. write_data = ROM_data;
  847. ROM_addr = 71;
  848. end
  849. D72:begin
  850. set_pos_x = 64;
  851. set_pos_y = 4;
  852. write_data = ROM_data;
  853. ROM_addr = 72;
  854. end
  855. D73:begin
  856. set_pos_x = 72;
  857. set_pos_y = 4;
  858. write_data = ROM_data;
  859. ROM_addr = 73;
  860. end
  861. D74:begin
  862. set_pos_x = 80;
  863. set_pos_y = 4;
  864. write_data = ROM_data;
  865. ROM_addr = 74;
  866. end
  867. D75:begin
  868. set_pos_x = 88;
  869. set_pos_y = 4;
  870. write_data = ROM_data;
  871. ROM_addr = 75;
  872. end
  873. D76:begin
  874. set_pos_x = 96;
  875. set_pos_y = 4;
  876. write_data = ROM_data;
  877. ROM_addr = 76;
  878. end
  879. D77:begin
  880. set_pos_x = 104;
  881. set_pos_y = 4;
  882. write_data = ROM_data;
  883. ROM_addr = 77;
  884. end
  885. D78:begin
  886. set_pos_x = 112;
  887. set_pos_y = 4;
  888. write_data = ROM_data;
  889. ROM_addr = 78;
  890. end
  891. D79:begin
  892. set_pos_x = 120;
  893. set_pos_y = 4;
  894. write_data = ROM_data;
  895. ROM_addr = 79;
  896. end
  897. //PAGGE5
  898. D80:begin
  899. set_pos_x = 0;
  900. set_pos_y = 5;
  901. write_data = ROM_data;
  902. ROM_addr = 80;
  903. end
  904. D81:begin
  905. set_pos_x = 8;
  906. set_pos_y = 5;
  907. write_data = ROM_data;
  908. ROM_addr = 81;
  909. end
  910. D82:begin
  911. set_pos_x = 16;
  912. set_pos_y = 5;
  913. write_data = ROM_data;
  914. ROM_addr = 82;
  915. end
  916. D83:begin
  917. set_pos_x = 24;
  918. set_pos_y = 5;
  919. write_data = ROM_data;
  920. ROM_addr = 83;
  921. end
  922. D84:begin
  923. set_pos_x = 32;
  924. set_pos_y = 5;
  925. write_data = ROM_data;
  926. ROM_addr = 84;
  927. end
  928. D85:begin
  929. set_pos_x = 40;
  930. set_pos_y = 5;
  931. write_data = ROM_data;
  932. ROM_addr = 85;
  933. end
  934. D86:begin
  935. set_pos_x = 48;
  936. set_pos_y = 5;
  937. write_data = ROM_data;
  938. ROM_addr = 86;
  939. end
  940. D87:begin
  941. set_pos_x = 56;
  942. set_pos_y = 5;
  943. write_data = ROM_data;
  944. ROM_addr = 87;
  945. end
  946. D88:begin
  947. set_pos_x = 64;
  948. set_pos_y = 5;
  949. write_data = ROM_data;
  950. ROM_addr = 88;
  951. end
  952. D89:begin
  953. set_pos_x = 72;
  954. set_pos_y = 5;
  955. write_data = ROM_data;
  956. ROM_addr = 89;
  957. end
  958. D90:begin
  959. set_pos_x = 80;
  960. set_pos_y = 5;
  961. write_data = ROM_data;
  962. ROM_addr = 90;
  963. end
  964. D91:begin
  965. set_pos_x = 88;
  966. set_pos_y = 5;
  967. write_data = ROM_data;
  968. ROM_addr = 91;
  969. end
  970. D92:begin
  971. set_pos_x = 96;
  972. set_pos_y = 5;
  973. write_data = ROM_data;
  974. ROM_addr = 92;
  975. end
  976. D93:begin
  977. set_pos_x = 104;
  978. set_pos_y = 5;
  979. write_data = ROM_data;
  980. ROM_addr = 93;
  981. end
  982. D94:begin
  983. set_pos_x = 112;
  984. set_pos_y = 5;
  985. write_data = ROM_data;
  986. ROM_addr = 94;
  987. end
  988. D95:begin
  989. set_pos_x = 120;
  990. set_pos_y = 5;
  991. write_data = ROM_data;
  992. ROM_addr = 95;
  993. end
  994. //PAGE6
  995. D96:begin
  996. set_pos_x = 0;
  997. set_pos_y = 6;
  998. write_data = ROM_data;
  999. ROM_addr = 96;
  1000. end
  1001. D97:begin
  1002. set_pos_x = 8;
  1003. set_pos_y = 6;
  1004. write_data = ROM_data;
  1005. ROM_addr = 97;
  1006. end
  1007. D98:begin
  1008. set_pos_x = 16;
  1009. set_pos_y = 6;
  1010. write_data = ROM_data;
  1011. ROM_addr = 98;
  1012. end
  1013. D99:begin
  1014. set_pos_x = 24;
  1015. set_pos_y = 6;
  1016. write_data = ROM_data;
  1017. ROM_addr = 99;
  1018. end
  1019. D100:begin
  1020. set_pos_x = 32;
  1021. set_pos_y = 6;
  1022. write_data = ROM_data;
  1023. ROM_addr = 100;
  1024. end
  1025. D101:begin
  1026. set_pos_x = 40;
  1027. set_pos_y = 6;
  1028. write_data = ROM_data;
  1029. ROM_addr = 101;
  1030. end
  1031. D102:begin
  1032. set_pos_x = 48;
  1033. set_pos_y = 6;
  1034. write_data = ROM_data;
  1035. ROM_addr = 102;
  1036. end
  1037. D103:begin
  1038. set_pos_x = 56;
  1039. set_pos_y = 6;
  1040. write_data = ROM_data;
  1041. ROM_addr = 103;
  1042. end
  1043. D104:begin
  1044. set_pos_x = 64;
  1045. set_pos_y = 6;
  1046. write_data = ROM_data;
  1047. ROM_addr = 104;
  1048. end
  1049. D105:begin
  1050. set_pos_x = 72;
  1051. set_pos_y = 6;
  1052. write_data = ROM_data;
  1053. ROM_addr = 105;
  1054. end
  1055. D106:begin
  1056. set_pos_x = 80;
  1057. set_pos_y = 6;
  1058. write_data = ROM_data;
  1059. ROM_addr = 106;
  1060. end
  1061. D107:begin
  1062. set_pos_x = 88;
  1063. set_pos_y = 6;
  1064. write_data = ROM_data;
  1065. ROM_addr = 107;
  1066. end
  1067. D108:begin
  1068. set_pos_x = 96;
  1069. set_pos_y = 6;
  1070. write_data = ROM_data;
  1071. ROM_addr = 108;
  1072. end
  1073. D109:begin
  1074. set_pos_x = 104;
  1075. set_pos_y = 6;
  1076. write_data = ROM_data;
  1077. ROM_addr = 109;
  1078. end
  1079. D110:begin
  1080. set_pos_x = 112;
  1081. set_pos_y = 6;
  1082. write_data = ROM_data;
  1083. ROM_addr = 110;
  1084. end
  1085. D111:begin
  1086. set_pos_x = 120;
  1087. set_pos_y = 6;
  1088. write_data = ROM_data;
  1089. ROM_addr = 111;
  1090. end
  1091. //PAGE7
  1092. D112:begin
  1093. set_pos_x = 0;
  1094. set_pos_y = 7;
  1095. write_data = ROM_data;
  1096. ROM_addr = 112;
  1097. end
  1098. D113:begin
  1099. set_pos_x = 8;
  1100. set_pos_y = 7;
  1101. write_data = ROM_data;
  1102. ROM_addr = 113;
  1103. end
  1104. D114:begin
  1105. set_pos_x = 16;
  1106. set_pos_y = 7;
  1107. write_data = ROM_data;
  1108. ROM_addr = 114;
  1109. end
  1110. D115:begin
  1111. set_pos_x = 24;
  1112. set_pos_y = 7;
  1113. write_data = ROM_data;
  1114. ROM_addr = 115;
  1115. end
  1116. D116:begin
  1117. set_pos_x = 32;
  1118. set_pos_y = 7;
  1119. write_data = ROM_data;
  1120. ROM_addr = 116;
  1121. end
  1122. D117:begin
  1123. set_pos_x = 40;
  1124. set_pos_y = 7;
  1125. write_data = ROM_data;
  1126. ROM_addr = 117;
  1127. end
  1128. D118:begin
  1129. set_pos_x = 48;
  1130. set_pos_y = 7;
  1131. write_data = ROM_data;
  1132. ROM_addr = 118;
  1133. end
  1134. D119:begin
  1135. set_pos_x = 56;
  1136. set_pos_y = 7;
  1137. write_data = ROM_data;
  1138. ROM_addr = 119;
  1139. end
  1140. D120:begin
  1141. set_pos_x = 64;
  1142. set_pos_y = 7;
  1143. write_data = ROM_data;
  1144. ROM_addr = 120;
  1145. end
  1146. D121:begin
  1147. set_pos_x = 72;
  1148. set_pos_y = 7;
  1149. write_data = ROM_data;
  1150. ROM_addr = 121;
  1151. end
  1152. D122:begin
  1153. set_pos_x = 80;
  1154. set_pos_y = 7;
  1155. write_data = ROM_data;
  1156. ROM_addr = 122;
  1157. end
  1158. D123:begin
  1159. set_pos_x = 88;
  1160. set_pos_y = 7;
  1161. write_data = ROM_data;
  1162. ROM_addr = 123;
  1163. end
  1164. D124:begin
  1165. set_pos_x = 96;
  1166. set_pos_y = 7;
  1167. write_data = ROM_data;
  1168. ROM_addr = 124;
  1169. end
  1170. D125:begin
  1171. set_pos_x = 104;
  1172. set_pos_y = 7;
  1173. write_data = ROM_data;
  1174. ROM_addr = 125;
  1175. end
  1176. D126:begin
  1177. set_pos_x = 112;
  1178. set_pos_y = 7;
  1179. write_data = ROM_data;
  1180. ROM_addr = 126;
  1181. end
  1182. D127:begin
  1183. set_pos_x = 120;
  1184. set_pos_y = 7;
  1185. write_data = ROM_data;
  1186. ROM_addr = 127;
  1187. end
  1188. default: begin
  1189. set_pos_x = 0;
  1190. set_pos_y = 0;
  1191. write_data= 64'd0;
  1192. end
  1193. endcase
  1194. end
  1195. end
  1196. //初始化写使能、发送的数据控制
  1197. always @(*) begin
  1198. if(!rst_n)begin
  1199. DC_in = 0;
  1200. SPI_data = 0;
  1201. SPI_send = 0;
  1202. end
  1203. else begin
  1204. case(cstate)
  1205. INIT:begin
  1206. DC_in = DC_init;
  1207. SPI_data = SPI_data_init;
  1208. SPI_send = SPI_send_init;
  1209. end
  1210. CLR:begin
  1211. DC_in = DC_clear;
  1212. SPI_data = SPI_data_clear;
  1213. SPI_send = SPI_send_clear;
  1214. end
  1215. D0,D1,D2,D3,D4,D5,D6,D7,D8,D9,
  1216. D10,D11,D12,D13,D14,D15,D16,D17,D18,D19,
  1217. D20,D21,D22,D23,D24,D25,D26,D27,D28,D29,
  1218. D30,D31,D32,D33,D34,D35,D36,D37,D38,D39,
  1219. D40,D41,D42,D43,D44,D45,D46,D47,D48,D49,
  1220. D50,D51,D52,D53,D54,D55,D56,D57,D58,D59,
  1221. D60,D61,D62,D63,D64,D65,D66,D67,D68,D69,
  1222. D70,D71,D72,D73,D74,D75,D76,D77,D78,D79,
  1223. D80,D81,D82,D83,D84,D85,D86,D87,D88,D89,
  1224. D90,D91,D92,D93,D94,D95,D96,D97,D98,D99,
  1225. D100,D101,D102,D103,D104,D105,D106,D107,D108,D109,
  1226. D110,D111,D112,D113,D114,D115,D116,D117,D118,D119,
  1227. D120,D121,D122,D123,D124,D125,D126,D127:begin
  1228. DC_in = DC_write;
  1229. SPI_data = SPI_data_write;
  1230. SPI_send = SPI_send_write;
  1231. end
  1232. default:begin
  1233. DC_in = 0;
  1234. SPI_data = 0;
  1235. SPI_send = 0;
  1236. end
  1237. endcase
  1238. end
  1239. end
  1240. endmodule

五、仿真结果

初始化

 清屏后发送数据

 testbench:

  1. module top_tb;
  2. // Ports
  3. reg sys_clk = 0;
  4. reg sys_rst_n = 0;
  5. wire sclk;
  6. wire sck;
  7. wire res;
  8. wire MOSI;
  9. wire CS;
  10. wire DC;
  11. top top_dut(
  12. .sys_clk(sys_clk),
  13. .sys_rst_n(sys_rst_n),
  14. .sclk(sclk),
  15. .sck(sck),
  16. .res(res),
  17. .MOSI(MOSI),
  18. .CS(CS),
  19. .DC(DC)
  20. );
  21. initial begin
  22. begin
  23. #10000;
  24. sys_rst_n = 1;
  25. // $finish;
  26. end
  27. end
  28. always #5 sys_clk = ! sys_clk ;
  29. endmodule

六、板级验证

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/640604
推荐阅读
相关标签
  

闽ICP备14008679号