模块调用时去掉控制器control节拍发生器sgen就没有问题,是00000001的循环左移;但是加上控制器就仿真有错误,输出的t7~t0就是00000000,00000010,00001100,00010000,01100000,10000000,00000001。我感觉是信号t0...t7的问题,但是t0到t7在控制器中是输入信号,在节拍发生器是输出信号,其他地方没有对t0到t7进行修改,为什么有错?各位大神,帮帮忙看一下呗。QQ截图20180708110932.png (31.79 KB 下载次数: 0)
在软件上的时间 0.5s 左右 实际时间运行了大概20秒 软件时间跟实际时间不同步 这是什么问题?
我现在在学CPLD和FPGA,打算写一个CPLD驱动串行LCD12232的程序。想了一下,感觉很难写。那位大神,给个思路呗,谢谢!
工程中有很多原理图,如何在导出元件清单时,只导出某一张原理图,而不是导出所有的元件的呢?
我写了个CPLD驱动HT1621的程序,定义了一个函数。可是编译有警告。Warning (10241): Verilog HDL Function Declaration warning at ht1621.v(530): function "HT1621_Cmd5" may return a Don't Care value because its output register may not be assigned a value in every possible path through the function这个怎么消除啊?谢谢!
我写了个CPLD驱动DS18B20的程序,用LCD1602显示。可是老是显示00.0.哪里出错啦?高手给看看。module ds18b20( input CLOCK_50 input Q_KEY inout DS18B20 output lcd_p //Backlight Source + output lcd_n //Backlight Source - output lcd_rs //0:write order; 1:write data output lcd_rw //0:write data; 1:read data output lcd_en //negedge output [7:0] lcd_data);wire [11:0] t_buf;reg ClkEnable;reg [3:0] address;ds18b20_drive ds18b20_u0( .nReset(Q_KEY) .ClkEnable(ClkEnable) .address(address) .clk(CLOCK_50) .data(t_buf) .icdata(DS18B20) );ds18b20_lcd lcd1602( .clk (CLOCK_50) .Q_KEY (Q_KEY) .lcd_p (lcd_p) .lcd_n (lcd_n) .lcd_rs (lcd_rs) .lcd_rw (lcd_rw) .lcd_en (lcd_en) .lcd_data (lcd_data) .data (t_buf));endmodule这是顶层文件。/************************************************************************************************ name:LCD1602_Driver ************************************************** author:made by zzuxzt *************************************************** time:2014.5.18 *******************************************************************************************************/module ds18b20_lcd(input clk //50M input Q_KEY output lcd_p //Backlight Source + output lcd_n //Backlight Source - output reg lcd_rs //0:write order; 1:write data output lcd_rw //0:write data; 1:read data output reg lcd_en //negedge output reg [7:0] lcd_data input [11:0] data); //--------------------lcd1602 order----------------------------parameter Mode_Set = 8'h31 Cursor_Set = 8'h0c Address_Set = 8'h06 Clear_Set = 8'h01;/****************************LCD1602 Display Data****************************/ wire [7:0] data0data1data2; //counter datawire [7:0] addr; //write address//---------------------------------1s counter-----------------------------------reg [31:0] cnt1;reg [7:0] data_r0data_r1;/*always@(posedge clk or negedge Q_KEY)begin if(!Q_KEY) begin cnt1 <= 1'b0; data_r0 <= 1'b0; data_r1 <= 1'b0; end else if(cnt1==32'd50000000) begin if(data_r0==8'd9) begin data_r0 <= 1'b0; if(data_r1==8'd9) data_r1 <= 1'b0; else data_r1 <= data_r1 + 1'b1; end else data_r0 <= data_r0 + 1'b1; cnt1 <= 1'b0; end else cnt1 <= cnt1 + 1'b1;end*///assign data0 = 8'h30 + data_r0 ; //assign data1 = 8'h30 + data_r1 ;assign data0 = 8'h30 + data[7:4] ; assign data1 = 8'h30 + data[11:8] ;assign data2 = 8'h30 + data[3:0];//-------------------address------------------assign addr = 8'h80;/****************************LCD1602 Driver****************************/ //-----------------------lcd1602 clk_en---------------------reg [31:0] cnt;reg lcd_clk_en;always @(posedge clk or negedge Q_KEY) begin if(!Q_KEY) begin cnt <= 1'b0; lcd_clk_en <= 1'b0; end else if(cnt == 32'h24999) //500us begin lcd_clk_en <= 1'b1; cnt <= 1'b0; end else begin cnt <= cnt + 1'b1; lcd_clk_en <= 1'b0; endend //-----------------------lcd1602 display state-------------------------------------------reg [4:0] state;always@(posedge clk or negedge Q_KEY)begin if(!Q_KEY) begin state <= 1'b0; lcd_rs <= 1'b0; lcd_en <= 1'b0; lcd_data <= 1'b0; end else if(lcd_clk_en) begin case(state) //-------------------init_state--------------------- 5'd0: begin lcd_rs <= 1'b0; lcd_en <= 1'b1; lcd_data <= Mode_Set; state <= state + 1'd1; end 5'd1: begin lcd_en <= 1'b0; state <= state + 1'd1; end 5'd2: begin lcd_rs <= 1'b0; lcd_en <= 1'b1; lcd_data <= Cursor_Set; state <= state + 1'd1; end 5'd3: begin lcd_en <= 1'b0; state <= state + 1'd1; end 5'd4: begin lcd_rs <= 1'b0; lcd_en <= 1'b1; lcd_data <= Address_Set; state <= state + 1'd1; end 5'd5: begin lcd_en <= 1'b0; state <= state + 1'd1; end 5'd6: begin lcd_rs <= 1'b0; lcd_en <= 1'b1; lcd_data <= Clear_Set; state <= state + 1'd1; end 5'd7: begin lcd_en <= 1'b0; state <= state + 1'd1; end //--------------------work state-------------------- 5'd8: begin lcd_rs <= 1'b0; lcd_en <= 1'b1; lcd_data <= addr; //write addr state <= state + 1'd1; end 5'd9: begin lcd_en <= 1'b0; state <= state + 1'd1; end 5'd10: begin lcd_rs <= 1'b1; lcd_en <= 1'b1; lcd_data <= "C"; //write data state <= state + 1'd1; end 5'd11: begin lcd_en <= 1'b0; state <= state + 1'd1; end 5'd12: begin lcd_rs <= 1'b1; lcd_en <= 1'b1; lcd_data <= "n"; //write data state <= state + 1'd1; end 5'd13: begin lcd_en <= 1'b0; state <= state + 1'd1; end 5'd14: begin lcd_rs <= 1'b1; lcd_en <= 1'b1; lcd_data <= "t"; //write data state <= state + 1'd1; end 5'd15: begin lcd_en <= 1'b0; state <= state + 1'd1; end 5'd16: begin lcd_rs <= 1'b1; lcd_en <= 1'b1; lcd_data <= ":"; //write data state <= state + 1'd1; end 5'd17: begin lcd_en <= 1'b0; state <= state + 1'd1; end 5'd18: begin lcd_rs <= 1'b1; lcd_en <= 1'b1; lcd_data <= data1; //write data: tens digit state <= state + 1'd1; end 5'd19: begin lcd_en <= 1'b0; state <= state + 1'd1; end 5'd20: begin lcd_rs <= 1'b1; lcd_en <= 1'b1; lcd_data <= data0; //write data: single digit state <= state + 1'd1; end 5'd21: begin lcd_en <= 1'b0; //state <= 5'd8; state <= state + 1'd1; end 5'd22:begin lcd_rs <= 1'b1; lcd_en <= 1'b1; lcd_data <= "."; //write data: single digit state <= state + 1'd1; end 5'd23: begin lcd_en <= 1'b0; //state <= 5'd8; state <= state + 1'd1; end 5'd24:begin lcd_rs <= 1'b1; lcd_en <= 1'b1; lcd_data <= data2; //write data: single digit state <= state + 1'd1; end 5'd25: begin lcd_en <= 1'b0; state <= 5'd8; //state <= state + 1'd1; end default: state <= 5'bxxxxx; endcase endendassign lcd_rw = 1'b0; //only write//------------------backlight driver----------------assign lcd_n = 1'b0;assign lcd_p = 1'b1;endmodule这是LCD驱动。module ds18b20_drive(nResetClkEnableaddressclkdataicdata);input [3:0] address;input nResetClkEnableclk;//clk 1Mhzoutput [7:0] data;inout [15:0] icdata;wire [7:0] data;reg [15:0] icdata;//initial data = 8'bzzzzzzzz; reg[4:0] ij; //一个字8个位,多出一个数量级已用于判断parameter state_0 = 0;parameter state_1 = 1;parameter state_2 = 2;parameter state_3 = 3;parameter state_4 = 4;parameter state_5 = 5;parameter state_6 = 6;parameter state_7 = 7;parameter state_8 = 8;parameter state_9 = 9;parameter state_10 = 10;parameter state_11 = 11;parameter state_12 = 12;parameter state_13 = 13;parameter state_14 = 14;parameter state_15 = 15;always@(negedge clk or negedge nReset)begin if(!nReset) begin end else if(ClkEnable) begin CmdSETDS18B20; end endassign data = Result[0];reg Flag_Rst; //复位完成标志reg [4:0] Rststate; //复位状态 reg [10:1] CountRstStep; //复位计数器 1024task Rst_DS18B20;begin case(Rststate) state_0 : //out 1 keep 1us begin Flag_Rst <= 0; //复位进行中 icdata <= 16'b1111_1111_1111_1111; //总线拉高16'b1111_1111_1111_1111 Rststate <= state_1; CountRstStep <= 0; end state_1 : begin icdata <= 0; //总线拉低 if(CountRstStep > 600) //拉低时间600us begin CountRstStep <= 0; //计数器清0 Rststate <= state_2; end else begin CountRstStep <= CountRstStep + 1; Rststate <= state_1; //计时未到 end end state_2 : begin icdata <= 16'b1111_1111_1111_1111; //dbgu //总线拉高 if(CountRstStep > 50) //拉高时间50us begin CountRstStep <= 0; //计数器清0 Rststate <= state_3; end else begin CountRstStep <= CountRstStep + 1; Rststate <= state_2; //计时未到 end end state_3 : begin icdata <= 16'bzzzz_zzzz_zzzz_zzzz; //释放总线 Rststate <= state_4; end state_4 : begin Rststate <= state_5; end state_5 : begin if(icdata == 16'b1111_1111_1111_1111) //初始化完成 begin CountRstStep <= 0; Rststate <= state_6; //结束 end else begin if(CountRstStep > 20) begin CountRstStep <= 0; Rststate <= state_6; //state_0 end else begin CountRstStep <= CountRstStep + 1; Rststate <= state_5; end end end state_6 : begin if(CountRstStep == 200) begin CountRstStep <= 0; Rststate <= state_7; end else begin CountRstStep <= CountRstStep + 1; Rststate <= state_6; end end state_7 : begin Flag_Rst <= 1; //初始化完成 CountRstStep <= 0; Rststate <= state_0; //回到原点 end default : begin Rststate <= state_0; CountRstStep <= 0; end endcaseendendtaskreg Flag_Write; //写命令完成标志与写位reg[4:0] Writestate; //写命令状态task Write_DS18B20;input [7:0] dcmd; //命令reg[7:0] indcmd;reg wBit;begin case(Writestate) state_0 : begin Flag_Write <= 0; //写命令过程中 Writestate <= state_1; indcmd <= dcmd; i <= 0; end state_1 : begin if(i < 8) begin wBit_DS18B20(indcmd[0]); if(Flag_wBit) //写完1位 begin indcmd = indcmd >> 1; //右移1位 i <= i + 1; //位数加1 end Writestate <= state_1; //重复加写位 end else //写完8位 begin Writestate <= state_2; i <= 0; end end state_2 : begin Flag_Write <= 1; //写命令完毕 indcmd <= 0; Writestate <= state_0; end default : begin Flag_Write <= 0; Writestate <= state_0; end endcaseendendtask reg Flag_wBit; //写位完成标志reg[4:0] WriteBitstate; //写位命令reg[8:1] CountWbitStep; //写位计数器task wBit_DS18B20;input wiBit; //位信息begin case(WriteBitstate) state_0 : begin Flag_wBit <= 0; //写位进行中 icdata <= 16'b1111_1111_1111_1111; WriteBitstate <= state_1; CountWbitStep <= 0; end state_1 : begin icdata <= 0; //总线拉低 if(wiBit)WriteBitstate <= state_2; //写1的命令 else WriteBitstate <= state_4; //写0的命令 end state_2 : begin if(CountWbitStep >= 3) //维持低电平3us begin CountWbitStep <= 0; icdata <= 16'b1111_1111_1111_1111; WriteBitstate <= state_3; end else begin CountWbitStep <= CountWbitStep + 1; WriteBitstate <= state_2; end end state_3 : begin if(CountWbitStep >= 60) //维持拉高电平60us begin CountWbitStep <= 0; WriteBitstate <= state_6; end else begin CountWbitStep <= CountWbitStep + 1; WriteBitstate <= state_3; end end state_4 : begin if(CountWbitStep >= 60) //维持低电平60us begin CountWbitStep <= 0; WriteBitstate <= state_5; end else begin icdata <= 0; CountWbitStep <= CountWbitStep + 1; WriteBitstate <= state_4; end end state_5 : begin if(CountWbitStep >= 3) //拉高总线3us begin CountWbitStep <= 0; WriteBitstate <= state_6; end else begin icdata <= 16'b1111_1111_1111_1111; CountWbitStep <= CountWbitStep + 1; WriteBitstate <= state_5; end end state_6 : begin Flag_wBit <= 1; //写位命令完毕 CountWbitStep <= 0; WriteBitstate <= state_0; end default : begin Flag_wBit <= 0; CountWbitStep <= 0; WriteBitstate <= state_0; end endcaseendendtaskreg[7:0] ResultDS18B20[15:0]; //读到的结果reg[15:0] temp[7:0];reg Flag_Read; //读命令标志reg [4:0] Readstate; //读命令状态reg t;task Read_DS18B20;begin case(Readstate) state_0 : begin Flag_Read <= 0; //读命令进行中 Readstate <= state_1; j <= 0; end state_1 : begin if( j < 8 ) begin rBit_DS18B20; if( Flag_rBit ) begin j <= j + 1; end Readstate <= state_1; end else begin j <= 0; i <= 0; t <= 1; Readstate <= state_2; end end state_2 : begin if( i < 16 ) begin if( temp[j][i] ) begin ResultDS18B20[i] = ResultDS18B20[i] | 8'b1000_0000; end if( j < 7 ) ResultDS18B20[i] = ResultDS18B20[i] >> 1; i <= i + 1; Readstate <= state_2; end else begin i <= 0; Readstate <= state_3; end end state_3 : begin if( j < 7 ) begin j <= j + 1; Readstate <= state_2; end else begin i <= 0; j <= 0; Readstate <= state_4; end end state_4 : begin Flag_Read <= 1; //读命令完成 Readstate <= state_0; end default : begin Flag_Read <= 0; Readstate <= state_0; end endcaseend endtask reg Flag_rBit; //读位命令标志reg[4:0] ReadBitstate; //读位命令状态reg[6:1] CountRbitStep; //读位命令计时器task rBit_DS18B20;begin case(ReadBitstate) state_0 : begin Flag_rBit <= 0; //读位命令进行中 icdata <= 16'b1111_1111_1111_1111; CountRbitStep <= 0; ReadBitstate <= state_1; end state_1 : begin if(CountRbitStep >= 3) //保持低电平3us begin icdata <= 16'b1111_1111_1111_1111; icdata <= 16'bzzzz_zzzz_zzzz_zzzz; //改为输入 CountRbitStep <= 0; ReadBitstate <= state_2; end else begin icdata <= 0; //总线拉低 CountRbitStep <= CountRbitStep + 1; ReadBitstate <= state_1; end end state_2 : begin if(CountRbitStep >= 10) //维持输入状态10us begin temp[j] <= icdata; CountRbitStep <= 0; ReadBitstate <= state_3; end else begin CountRbitStep <= CountRbitStep + 1; ReadBitstate <= state_2; end end state_3 : begin if(CountRbitStep >= 60) //维持60us输入 begin CountRbitStep <= 0; ReadBitstate <= state_4; end else begin CountRbitStep <= CountRbitStep + 1; ReadBitstate <= state_3; end end state_4 : begin Flag_rBit <= 1; //读位命令完毕 CountRbitStep <= 0; ReadBitstate <= state_0; end default : begin Flag_rBit <= 0; CountRbitStep <= 0; ReadBitstate <= state_0; end endcaseend endtask reg Flag_CmdSET;reg [4:0] CmdSETstate;reg [16:1] Count65535;reg [4:1] Count12;reg [7:0] Resultl[15:0]Resulth[15:0]Result[15:0];task CmdSETDS18B20;begin case(CmdSETstate) state_0 : begin Flag_CmdSET <= 0; Rst_DS18B20; if(!Flag_Rst)CmdSETstate <= state_0; else CmdSETstate <= state_1; end state_1 : begin// Write_DS18B20(8'hcc);// Write_DS18B20(8'h44); if(!Flag_Write)CmdSETstate <= state_1; else CmdSETstate <= state_2; end state_2 : begin// Write_DS18B20(8'h44);// Write_DS18B20(8'hcc); if(!Flag_Write)CmdSETstate <= state_2; else CmdSETstate <= state_3; end state_3 : begin if(Count65535 == 65535) begin Count65535 <= 0; CmdSETstate <= state_4; end else begin Count65535 <= Count65535 + 1; CmdSETstate <= state_3; end end state_4 : begin if(Count12 == 12) begin Count12 <= 0; CmdSETstate <= state_5; end else begin Count12 <= Count12 + 1; CmdSETstate <= state_3; end end state_5 : begin Rst_DS18B20; if(!Flag_Rst)CmdSETstate <= state_5; else CmdSETstate <= state_6; end state_6 : begin// Write_DS18B20(8'hcc);// Write_DS18B20(8'hbe); if(!Flag_Write)CmdSETstate <= state_6; else CmdSETstate <= state_7; end state_7 : begin// Write_DS18B20(8'hbe);// Write_DS18B20(8'hcc); if(!Flag_Write)CmdSETstate <= state_7; else CmdSETstate <= state_8; end state_8 : begin Read_DS18B20; if(!Flag_Read)CmdSETstate <= state_8; else begin i <= 0; CmdSETstate <= state_9; end end state_9 : begin if( i < 16 ) begin Resultl[i] = ResultDS18B20[i]; i <= i + 1; CmdSETstate <= state_9; end else begin i <= 0; CmdSETstate <= state_10; end end state_10 : begin Read_DS18B20; if(!Flag_Read)CmdSETstate <= state_10; else begin i <= 0; CmdSETstate <= state_11; end end state_11 : begin if( i < 16) begin Resulth[i] = ResultDS18B20[i]; i <= i + 1; CmdSETstate <= state_11; end else begin i <= 0; CmdSETstate <= state_12; end end state_12 : begin if( i < 16 ) begin Result[i] = (Resulth[i] << 4)|(Resultl[i] >> 4); i <= i + 1; CmdSETstate <= state_12; end else begin i <= 0; CmdSETstate <= state_13; end end state_13 : begin Flag_CmdSET <= 1; CmdSETstate <= state_0; end default : begin Flag_CmdSET <= 0; CmdSETstate <= state_0; end endcaseendendtaskendmodule这是DS18B20驱动
Cadence软件现在是比较常用的,入门级别的书籍也比较多常见,但相对提高些的,想进阶的书籍却不多见,所以想各位大神推荐一下!
先上程序:module ht1621(input clkinput rst_noutput reg sdiooutput reg sclkoutput reg stb);reg [15:0] olddata;reg [4:0] currentstate;parameter s1 = 5'b0_0001;parameter s2 = 5'b0_0010;//设置工作模式parameter s3 = 5'b0_0011;parameter s4 = 5'b0_0100;//固定地址写数据parameter s5 = 5'b0_0101;//parameter s6 = 5'b0_0110;//S6和S5状态设置扫描限值寄存器parameter s7 = 4'b0_0111;//parameter s8 = 5'b0_1000; //S7和S8状态 设置正常显示模式parameter s10 =5'b0_1010;//parameter s11 =5'b0_1011;//s10和是1状态 送入显示的数据parameter Init=5'b1_1110;parameter Init1=5'b1_1111;reg [5:0]counter;parameter seg1 = 16'h14abseg2 = 16'h14bcseg3 = 16'h14cd //1.seg4 = 16'h14de //2seg5 = 16'h14ef //3seg6 = 16'h14ff; //4reg [2:0]cnt;//产生时钟always @(posedge clk)begin if(!rst_n) begincounter<=6'd0;sclk <= 1'b1; end else begin if(counter==6'd32) begin sclk <= ~sclk; counter<=6'd0; end else counter<=counter+6'd1; endendreg [3:0] sclk_cnt;//同步时钟计数器,15always @(posedge sclk or negedge rst_n)beginif(!rst_n) sclk_cnt <= 1'b0;else case(currentstate)Init1s2s4s6s8s11: if(4'd15 == sclk_cnt) sclk_cnt <= 1'b0;else sclk_cnt <= sclk_cnt + 1'b1;default: sclk_cnt <= 1'b0;endcaseendreg [15:0] data;//主状态机always @(posedge sclk or negedge rst_n)beginif(!rst_n) begin currentstate <=Init; cnt = 3'b0; endelsecase(currentstate)Init:currentstate <=Init1;Init1:begin if(4'd15 == sclk_cnt) //16个时钟周期将数据送出去currentstate <= s7;elsecurrentstate <= Init1;ends1: currentstate <= s2; //s1和S2状态设置译码寄存器s2:begin if(4'd15 == sclk_cnt) //16个时钟周期将数据送出去currentstate <= s3;elsecurrentstate <= s2;ends3: currentstate <= s4;//S3和S4状态设置亮度寄存器s4: begin if(4'd15 == sclk_cnt) //16个时钟周期将数据送出去currentstate <= s5;elsecurrentstate <= s4;ends5: currentstate <= s6;// S6和S5状态设置扫描限值寄存器s6: begin if(4'd15 == sclk_cnt) //16个时钟周期将数据送出去currentstate <= s10;else currentstate <= s6;ends7: currentstate <= s8;// S7和S8状态 设置正常显示模式s8: begin if(4'd15 == sclk_cnt) //16个时钟周期将数据送出去currentstate <= s1;else currentstate <= s8;end//初始化完成 s10: if(olddata != data)currentstate <= s11;// 正常送数据显示 elsecurrentstate <= s10;s11: begin if(4'd15 == sclk_cnt) //16个时钟周期将数据送出去begincurrentstate <= s10;cnt = cnt + 1'b1; endelse currentstate <= s11;end endcaseendalways @(posedge sclk or negedge rst_n)beginif(!rst_n)begin data <= 16'h0000; olddata <= 16'h0000; endelse case(currentstate)Init:data <= 16'h0852; //0b1000 0101 0010 1/3duty 4coms7: data <= 16'h0830; //0b1000 0011 0000 内部时钟s1: data <= 16'h080A; //0b1000 0000 1010 禁止看门狗 s3: data <= 16'h0802; //0b1000 0000 0010 打开系统振荡器 s5: data <= 16'h0806; //0b1000 0000 0110 打开LCD偏压s10: begin case(cnt)3'd0: data <= seg1;3'd1: data <= seg2;3'd2: data <= seg3;3'd3: data <= seg4;3'd4: data <= seg5;3'd5: data <= seg6;endcaseolddata <= data;end//{4'b0000dd4'b000dd};olddata <=16'h0c01;end//{4'b00004'd48'd6};olddata <= {4'b00004'd48'd6};;;end//16'h080e; //待显示的数据Init1s2s4s6s8s11: begin data <= data << 1; olddata <= olddata; end//循环移位 将高位送出default: begin data <= 16'h0000; olddata <= olddata; endendcaseend//----------数据串行---------always @(posedge sclk or negedge rst_n)beginif(!rst_n) sdio <= 1'b0;else case(currentstate)Init1s2s4s6s8s11: sdio <= data[15];default: sdio <= 1'b0;endcaseend//----------串行数据写有效LOAD----------always @(posedge sclk or negedge rst_n)beginif(!rst_n) stb <= 1'b1;else case(currentstate)Init1s2s4s6s8s11: stb <= 1'b0; //送数的时候处于低default: stb <= 1'b1; //非送数时候,拉高 锁存数据endcaseendendmodule可是下载到板子里,液晶一段也不亮。