我用CPLD驱动MAX7219数码管显示,传送16位参数成功了。

可是传送8位参数则不成功。代码如下:
  1. module MAX7219
  2.                                 (
  3.                                         input clk_i,
  4.                                         input rst_i,                                       
  5.                                         //inout wire  sdo_i,//串行数据回读
  6.                                         output reg sdin_o,//串行输出数据
  7.                                         output reg sclk_o,//串行时钟
  8.                                         output reg load_o//更新da寄存器
  9.                                        
  10.                                 //        input wire [3:0]add,
  11.                                         //input wire [15:0]segdata
  12.                                        
  13.                                  );
  14. reg [7:0] olddata;
  15. reg [22:0] currentstate;
  16. parameter s1 = 23'b000_0000_0000_0000_0000_0001;
  17. parameter s2 = 23'b000_0000_0000_0000_0000_0010;//s1和S2状态设置译码寄存器                 
  18. parameter s3 = 23'b000_0000_0000_0000_0000_0100;
  19. parameter s4 = 23'b000_0000_0000_0000_0000_1000;//S3和S4状态设置亮度寄存器
  20. parameter s5 = 23'b000_0000_0000_0000_0001_0000;//
  21. parameter s6 = 23'b000_0000_0000_0000_0010_0000;//S6和S5状态设置扫描限值寄存器
  22. parameter s7 = 23'b000_0000_0000_0000_0100_0000;//
  23. parameter s8 = 23'b000_0000_0000_0000_1000_0000; //S7和S8状态 设置正常显示模式
  24. parameter s9 = 23'b000_0000_0000_0001_0000_0000; //S7和S8状态 设置正常显示模式
  25. parameter s10 =23'b000_0000_0000_0010_0000_0000;//
  26. parameter s11 =23'b000_0000_0000_0100_0000_0000;//s10和是1状态 送入显示的数据
  27. parameter s12 = 23'b000_0000_0000_1000_0000_0000;
  28. parameter s13 = 23'b000_0000_0001_0000_0000_0000;//s1和S2状态设置译码寄存器                 
  29. parameter s14 = 23'b000_0000_0010_0000_0000_0000;
  30. parameter s15 = 23'b000_0000_0100_0000_0000_0000;//S3和S4状态设置亮度寄存器
  31. parameter s16 = 23'b000_0000_1000_0000_0000_0000;//
  32. parameter s17 = 23'b000_0001_0000_0000_0000_0000;//S6和S5状态设置扫描限值寄存器
  33. parameter s18 = 23'b000_0010_0000_0000_0000_0000;//
  34. parameter s20 = 23'b000_1000_0000_0000_0000_0000; //S7和S8状态 设置正常显示模式
  35. parameter s21 = 23'b001_0000_0000_0000_0000_0000; //S7和S8状态 设置正常显示模式
  36. //parameter s21 =26'b00_0001_0000_0000_0000_0000_0000;//
  37. //parameter s22 =26'b00_0010_0000_0000_0000_0000_0000;//s10和是1状态 送入显示的数据
  38. //parameter s23 =26'b00_0100_0000_0000_0000_0000_0000;//
  39. //parameter s24 =26'b00_1000_0000_0000_0000_0000_0000;//s10和是1状态 送入显示的数据
  40. parameter Init=23'b010_0000_0000_0000_0000_0000;
  41. parameter Init1=23'b100_0000_0000_0000_0000_0000;
  42. //reg sclk_o;
  43. reg [5:0]counter;
  44. parameter       
  45.                         seg1 = 8'h11,                                //1.
  46.                         seg2 = 8'h81,                                //2
  47.                         seg3 = 8'h12,                                //3
  48.                         seg4 = 8'h02,                                //4
  49.                         seg5 = 8'h13,                                //1.
  50.                         seg6 = 8'h03,                                //2
  51.                         seg7 = 8'h14,                                //3
  52.                         seg8 = 8'h09;                                //4
  53. reg [2:0]cnt;                       
  54. parameter         tics=30;       
  55.        
  56. task delaydisp;
  57. input[2:0] i;
  58.         repeat(tics)
  59.         begin
  60.         i=1;
  61.         i=2;
  62.         i=3;
  63.         end
  64. endtask
  65.         //产生时钟
  66. always @(posedge clk_i)
  67. begin
  68.   if(!rst_i) begin
  69.                 counter<=6'd0;
  70.                 sclk_o <= 1'b1;
  71.     end
  72.   else begin
  73.     if(counter==6'd9) begin
  74.       sclk_o <= ~sclk_o;
  75.       counter<=6'd0;
  76.       end
  77.     else counter<=counter+6'd1;
  78.     end
  79. end
  80. reg [2:0] sclk_cnt;//同步时钟计数器,7
  81. always @(posedge sclk_o or negedge rst_i)
  82. begin
  83.         if(!rst_i) sclk_cnt <= 1'b0;
  84.         else
  85.         case(currentstate)
  86.                 Init1,s2,s4,s6,s8,s10,s12,s14,s16,s18,s21:
  87.                         if(3'd7  == sclk_cnt)
  88.                                         sclk_cnt <= 1'b0;
  89.                         else         sclk_cnt <= sclk_cnt + 1'b1;
  90.                 default: sclk_cnt <= 1'b0;
  91.         endcase
  92. end
  93. //主状态机
  94. always @(posedge sclk_o or negedge rst_i)
  95. begin
  96.         if(!rst_i) begin currentstate <=Init; cnt = 3'b0; end
  97.         else
  98.         case(currentstate)
  99.         Init:currentstate <=Init1;
  100.         Init1:begin
  101.                         if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
  102.                                 currentstate <= s1;
  103.                         else
  104.                                 currentstate <= Init1;
  105.                 end
  106.         s1: currentstate <= s2;  //s1和S2状态设置译码寄存器       
  107.         s2:begin
  108.                         if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
  109.                                 currentstate <= s3;
  110.                         else
  111.                                 currentstate <= s2;
  112.                 end
  113.         s3: currentstate <= s4;//S3和S4状态设置亮度寄存器
  114.         s4: begin
  115.                         if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
  116.                                 currentstate <= s5;
  117.                         else
  118.                                 currentstate <= s4;       
  119.                 end       
  120.         s5: currentstate <= s6;//        S6和S5状态设置扫描限值寄存器
  121.         s6: begin
  122.                         if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
  123.                                 currentstate <= s7;
  124.                         else
  125.                    currentstate <= s6;
  126.                 end
  127.         s7: currentstate <= s8;//        S7和S8状态 设置正常显示模式
  128.         s8: begin
  129.                         if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
  130.                                 currentstate <= s9;
  131.                         else
  132.                    currentstate <= s8;
  133.                 end
  134.         s9: currentstate <= s10;//        S7和S8状态 设置正常显示模式
  135.         s10: begin
  136.                         if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
  137.                                 currentstate <= s11;
  138.                         else
  139.                    currentstate <= s10;
  140.                 end
  141.         s11: currentstate <= s12;//        S7和S8状态 设置正常显示模式
  142.         s12: begin
  143.                         if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
  144.                                 currentstate <= s13;
  145.                         else
  146.                    currentstate <= s12;
  147.                 end
  148.         s13: currentstate <= s14;//        S7和S8状态 设置正常显示模式
  149.         s14: begin
  150.                         if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
  151.                                 currentstate <= s15;
  152.                         else
  153.                    currentstate <= s14;
  154.                 end
  155.         s15: currentstate <= s16;//        S7和S8状态 设置正常显示模式
  156.         s16: begin
  157.                         if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
  158.                                 currentstate <= s17;
  159.                         else
  160.                    currentstate <= s16;
  161.                 end
  162.         s17: currentstate <= s18;//        S7和S8状态 设置正常显示模式
  163.         s18: begin
  164.                         if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
  165.                                 currentstate <= s20;
  166.                         else
  167.                    currentstate <= s18;
  168.                 end
  169.        
  170.         //初始化完成         
  171.         s20: if(olddata != data)
  172.                                 currentstate <= s21;//        正常送数据显示
  173.                   else
  174.                                 currentstate <= s20;
  175.         s21: begin
  176.                         if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
  177.                                 begin
  178.                                         currentstate <= s20;
  179.                                         cnt = cnt + 1'b1;
  180.                                 end       
  181.                         else
  182.                    currentstate <= s21;
  183.                 end         
  184.         endcase
  185. end
  186. //各状态的处理
  187. reg [7:0] data;
  188. always @(posedge sclk_o or negedge rst_i)
  189. begin
  190.         if(!rst_i)begin  data <= 8'h00; olddata <= 8'h00; end
  191.         else case(currentstate)
  192.                 Init:begin data <= 8'h0a;delaydisp(20); end
  193.                 s1:begin  data <= 8'h04;delaydisp(20); end  //正常显示模式
  194.                 s3:begin  data <= 8'h0c;delaydisp(20);        end//编码寄存器 ALL CODE B DECODE
  195.            s5:begin  data <= 8'h01;delaydisp(20);        end//亮度寄存器 ALL max on
  196.                 s7:begin  data <= 8'h09;delaydisp(20); end  //扫描限值寄存器 ALL on
  197.                 s9:begin  data <= 8'hff;delaydisp(20); end  //正常显示模式
  198.                 s11:begin  data <= 8'h0f;delaydisp(20); end        //编码寄存器 ALL CODE B DECODE
  199.            s13:begin  data <= 8'h01;delaydisp(20); end        //亮度寄存器 ALL max on
  200.                 s15:begin  data <= 8'h0b;delaydisp(20); end  //扫描限值寄存器 ALL on
  201.                 s17:begin  data <= 8'h07;delaydisp(20); end  //扫描限值寄存器 ALL on
  202.                 s20: begin
  203.                         case(cnt)
  204.                         3'd0: begin data <= seg1;delaydisp(20);  end
  205.                         3'd1: begin data <= seg2;delaydisp(20); end
  206.                         3'd2: begin data <= seg3;delaydisp(20); end
  207.                         3'd3: begin data <= seg4;delaydisp(20); end
  208.                         3'd4: begin data <= seg5;delaydisp(20); end
  209.                         3'd5: begin data <= seg6;delaydisp(20); end
  210.                         3'd6: begin data <= seg7;delaydisp(20); end
  211.                         3'd7: begin data <= seg8;delaydisp(20); end
  212.                         endcase
  213.                         olddata <= data;
  214.                 end //待显示的数据
  215.                 Init1,s2,s4,s6,s8,s10,s12,s14,s16,s18,s21: begin data <= data << 1;        olddata <= olddata; end//循环移位 将高位送出
  216.                 default: begin data <= 8'h00; olddata <= olddata; end
  217.         endcase
  218. end
  219. //----------数据串行---------
  220. always @(posedge sclk_o or negedge rst_i)
  221. begin
  222.         if(!rst_i) sdin_o <= 1'b0;
  223.         else case(currentstate)
  224.                 Init1,s2,s4,s6,s8,s10,s12,s14,s16,s18,s21: sdin_o <= data[7];
  225.                 default: sdin_o <= 1'b0;
  226.         endcase
  227. end
  228. //----------串行数据写有效LOAD----------
  229. always @(posedge sclk_o or negedge rst_i)
  230. begin
  231.         if(!rst_i) load_o <= 1'b1;
  232.         else case(currentstate)
  233.                 Init1,s2,s4,s6,s8,s10,s12,s14,s16,s18,s21: begin  load_o <= 1'b0; delaydisp(20); end //送数的时候处于低
  234.                 default: load_o <= 1'b1; //非送数时候,拉高 锁存数据
  235.         endcase
  236. end
  237. endmodule
我刻意加了延时函数,还是不行。
大侠看看,哪里有问题?谢谢!