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

可是传送8位参数则不成功。代码如下:
module MAX7219
  •                                 (
  •                                         input clk_i,
  •                                         input rst_i,                                       
  •                                         //inout wire  sdo_i,//串行数据回读
  •                                         output reg sdin_o,//串行输出数据
  •                                         output reg sclk_o,//串行时钟
  •                                         output reg load_o//更新da寄存器
  •                                        
  •                                 //        input wire [3:0]add,
  •                                         //input wire [15:0]segdata
  •                                        
  •                                  );
  • reg [7:0] olddata;
  • reg [22:0] currentstate;
  • parameter s1 = 23'b000_0000_0000_0000_0000_0001;
  • parameter s2 = 23'b000_0000_0000_0000_0000_0010;//s1和S2状态设置译码寄存器                 
  • parameter s3 = 23'b000_0000_0000_0000_0000_0100;
  • parameter s4 = 23'b000_0000_0000_0000_0000_1000;//S3和S4状态设置亮度寄存器
  • parameter s5 = 23'b000_0000_0000_0000_0001_0000;//
  • parameter s6 = 23'b000_0000_0000_0000_0010_0000;//S6和S5状态设置扫描限值寄存器
  • parameter s7 = 23'b000_0000_0000_0000_0100_0000;//
  • parameter s8 = 23'b000_0000_0000_0000_1000_0000; //S7和S8状态 设置正常显示模式
  • parameter s9 = 23'b000_0000_0000_0001_0000_0000; //S7和S8状态 设置正常显示模式
  • parameter s10 =23'b000_0000_0000_0010_0000_0000;//
  • parameter s11 =23'b000_0000_0000_0100_0000_0000;//s10和是1状态 送入显示的数据
  • parameter s12 = 23'b000_0000_0000_1000_0000_0000;
  • parameter s13 = 23'b000_0000_0001_0000_0000_0000;//s1和S2状态设置译码寄存器                 
  • parameter s14 = 23'b000_0000_0010_0000_0000_0000;
  • parameter s15 = 23'b000_0000_0100_0000_0000_0000;//S3和S4状态设置亮度寄存器
  • parameter s16 = 23'b000_0000_1000_0000_0000_0000;//
  • parameter s17 = 23'b000_0001_0000_0000_0000_0000;//S6和S5状态设置扫描限值寄存器
  • parameter s18 = 23'b000_0010_0000_0000_0000_0000;//
  • parameter s20 = 23'b000_1000_0000_0000_0000_0000; //S7和S8状态 设置正常显示模式
  • parameter s21 = 23'b001_0000_0000_0000_0000_0000; //S7和S8状态 设置正常显示模式
  • //parameter s21 =26'b00_0001_0000_0000_0000_0000_0000;//
  • //parameter s22 =26'b00_0010_0000_0000_0000_0000_0000;//s10和是1状态 送入显示的数据
  • //parameter s23 =26'b00_0100_0000_0000_0000_0000_0000;//
  • //parameter s24 =26'b00_1000_0000_0000_0000_0000_0000;//s10和是1状态 送入显示的数据
  • parameter Init=23'b010_0000_0000_0000_0000_0000;
  • parameter Init1=23'b100_0000_0000_0000_0000_0000;
  • //reg sclk_o;
  • reg [5:0]counter;
  • parameter       
  •                         seg1 = 8'h11,                                //1.
  •                         seg2 = 8'h81,                                //2
  •                         seg3 = 8'h12,                                //3
  •                         seg4 = 8'h02,                                //4
  •                         seg5 = 8'h13,                                //1.
  •                         seg6 = 8'h03,                                //2
  •                         seg7 = 8'h14,                                //3
  •                         seg8 = 8'h09;                                //4
  • reg [2:0]cnt;                       
  • parameter         tics=30;       
  •        
  • task delaydisp;
  • input[2:0] i;
  •         repeat(tics)
  •         begin
  •         i=1;
  •         i=2;
  •         i=3;
  •         end
  • endtask
  •         //产生时钟
  • always @(posedge clk_i)
  • begin
  •   if(!rst_i) begin
  •                 counter<=6'd0;
  •                 sclk_o <= 1'b1;
  •     end
  •   else begin
  •     if(counter==6'd9) begin
  •       sclk_o <= ~sclk_o;
  •       counter<=6'd0;
  •       end
  •     else counter<=counter+6'd1;
  •     end
  • end
  • reg [2:0] sclk_cnt;//同步时钟计数器,7
  • always @(posedge sclk_o or negedge rst_i)
  • begin
  •         if(!rst_i) sclk_cnt <= 1'b0;
  •         else
  •         case(currentstate)
  •                 Init1,s2,s4,s6,s8,s10,s12,s14,s16,s18,s21:
  •                         if(3'd7  == sclk_cnt)
  •                                         sclk_cnt <= 1'b0;
  •                         else         sclk_cnt <= sclk_cnt + 1'b1;
  •                 default: sclk_cnt <= 1'b0;
  •         endcase
  • end
  • //主状态机
  • always @(posedge sclk_o or negedge rst_i)
  • begin
  •         if(!rst_i) begin currentstate <=Init; cnt = 3'b0; end
  •         else
  •         case(currentstate)
  •         Init:currentstate <=Init1;
  •         Init1:begin
  •                         if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
  •                                 currentstate <= s1;
  •                         else
  •                                 currentstate <= Init1;
  •                 end
  •         s1: currentstate <= s2;  //s1和S2状态设置译码寄存器       
  •         s2:begin
  •                         if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
  •                                 currentstate <= s3;
  •                         else
  •                                 currentstate <= s2;
  •                 end
  •         s3: currentstate <= s4;//S3和S4状态设置亮度寄存器
  •         s4: begin
  •                         if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
  •                                 currentstate <= s5;
  •                         else
  •                                 currentstate <= s4;       
  •                 end       
  •         s5: currentstate <= s6;//        S6和S5状态设置扫描限值寄存器
  •         s6: begin
  •                         if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
  •                                 currentstate <= s7;
  •                         else
  •                    currentstate <= s6;
  •                 end
  •         s7: currentstate <= s8;//        S7和S8状态 设置正常显示模式
  •         s8: begin
  •                         if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
  •                                 currentstate <= s9;
  •                         else
  •                    currentstate <= s8;
  •                 end
  •         s9: currentstate <= s10;//        S7和S8状态 设置正常显示模式
  •         s10: begin
  •                         if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
  •                                 currentstate <= s11;
  •                         else
  •                    currentstate <= s10;
  •                 end
  •         s11: currentstate <= s12;//        S7和S8状态 设置正常显示模式
  •         s12: begin
  •                         if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
  •                                 currentstate <= s13;
  •                         else
  •                    currentstate <= s12;
  •                 end
  •         s13: currentstate <= s14;//        S7和S8状态 设置正常显示模式
  •         s14: begin
  •                         if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
  •                                 currentstate <= s15;
  •                         else
  •                    currentstate <= s14;
  •                 end
  •         s15: currentstate <= s16;//        S7和S8状态 设置正常显示模式
  •         s16: begin
  •                         if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
  •                                 currentstate <= s17;
  •                         else
  •                    currentstate <= s16;
  •                 end
  •         s17: currentstate <= s18;//        S7和S8状态 设置正常显示模式
  •         s18: begin
  •                         if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
  •                                 currentstate <= s20;
  •                         else
  •                    currentstate <= s18;
  •                 end
  •        
  •         //初始化完成         
  •         s20: if(olddata != data)
  •                                 currentstate <= s21;//        正常送数据显示
  •                   else
  •                                 currentstate <= s20;
  •         s21: begin
  •                         if(3'd7 == sclk_cnt) //8个时钟周期将数据送出去
  •                                 begin
  •                                         currentstate <= s20;
  •                                         cnt = cnt + 1'b1;
  •                                 end       
  •                         else
  •                    currentstate <= s21;
  •                 end         
  •         endcase
  • end
  • //各状态的处理
  • reg [7:0] data;
  • always @(posedge sclk_o or negedge rst_i)
  • begin
  •         if(!rst_i)begin  data <= 8'h00; olddata <= 8'h00; end
  •         else case(currentstate)
  •                 Init:begin data <= 8'h0a;delaydisp(20); end
  •                 s1:begin  data <= 8'h04;delaydisp(20); end  //正常显示模式
  •                 s3:begin  data <= 8'h0c;delaydisp(20);        end//编码寄存器 ALL CODE B DECODE
  •            s5:begin  data <= 8'h01;delaydisp(20);        end//亮度寄存器 ALL max on
  •                 s7:begin  data <= 8'h09;delaydisp(20); end  //扫描限值寄存器 ALL on
  •                 s9:begin  data <= 8'hff;delaydisp(20); end  //正常显示模式
  •                 s11:begin  data <= 8'h0f;delaydisp(20); end        //编码寄存器 ALL CODE B DECODE
  •            s13:begin  data <= 8'h01;delaydisp(20); end        //亮度寄存器 ALL max on
  •                 s15:begin  data <= 8'h0b;delaydisp(20); end  //扫描限值寄存器 ALL on
  •                 s17:begin  data <= 8'h07;delaydisp(20); end  //扫描限值寄存器 ALL on
  •                 s20: begin
  •                         case(cnt)
  •                         3'd0: begin data <= seg1;delaydisp(20);  end
  •                         3'd1: begin data <= seg2;delaydisp(20); end
  •                         3'd2: begin data <= seg3;delaydisp(20); end
  •                         3'd3: begin data <= seg4;delaydisp(20); end
  •                         3'd4: begin data <= seg5;delaydisp(20); end
  •                         3'd5: begin data <= seg6;delaydisp(20); end
  •                         3'd6: begin data <= seg7;delaydisp(20); end
  •                         3'd7: begin data <= seg8;delaydisp(20); end
  •                         endcase
  •                         olddata <= data;
  •                 end //待显示的数据
  •                 Init1,s2,s4,s6,s8,s10,s12,s14,s16,s18,s21: begin data <= data << 1;        olddata <= olddata; end//循环移位 将高位送出
  •                 default: begin data <= 8'h00; olddata <= olddata; end
  •         endcase
  • end
  • //----------数据串行---------
  • always @(posedge sclk_o or negedge rst_i)
  • begin
  •         if(!rst_i) sdin_o <= 1'b0;
  •         else case(currentstate)
  •                 Init1,s2,s4,s6,s8,s10,s12,s14,s16,s18,s21: sdin_o <= data[7];
  •                 default: sdin_o <= 1'b0;
  •         endcase
  • end
  • //----------串行数据写有效LOAD----------
  • always @(posedge sclk_o or negedge rst_i)
  • begin
  •         if(!rst_i) load_o <= 1'b1;
  •         else case(currentstate)
  •                 Init1,s2,s4,s6,s8,s10,s12,s14,s16,s18,s21: begin  load_o <= 1'b0; delaydisp(20); end //送数的时候处于低
  •                 default: load_o <= 1'b1; //非送数时候,拉高 锁存数据
  •         endcase
  • end
  • endmodule
  • 复制代码
    我刻意加了延时函数,还是不行。
    大侠看看,哪里有问题?谢谢!