1. 程式人生 > >第一次用verilog除錯串列埠(傳送、接收)

第一次用verilog除錯串列埠(傳送、接收)

1、首先是傳送,程式如下

`timescale 1ns / 1ps

module send(in_data,out_data,en,clk); 
			
input clk;
input[7:0] in_data;
input en;
output reg out_data;

reg [12:0] timer;
reg[7:0]  in_buffer;
//reg tx_flag;



always @(posedge clk) 
begin 
	if(en==1) 
	  begin
		if(timer==20)
		in_buffer<=in_data; 
		//in_buffer<=8'b00000010;
		if(timer<4774)    
				timer<=timer+1'b1;
				else
				begin
					timer<=0;
					in_buffer<=0;
				end
	  end		
end
 
always @(posedge clk)
   begin
	if(en==1)
	begin
	
       case(timer)
           
           13'd0:
				begin
                 out_data<=0;
				 end
           13'd434: 
                 out_data<=in_buffer[0];//?????????
           13'd868:
                 out_data<=in_buffer[1];
           13'd1302:
                 out_data<=in_buffer[2];
           13'd1736:
                 out_data<=in_buffer[3];
           13'd2170:
                 out_data<=in_buffer[4];
           13'd2604:
                 out_data<=in_buffer[5];           
           13'd3038:
                 out_data<=in_buffer[6];
           13'd3472:
                 out_data<=in_buffer[7];
           13'd3906:
                 out_data<=0;
           13'd4340: 
				        begin		   
                 out_data<=1'b1;
				       end
       endcase    
    end
else
out_data<=1'bz;	 
   end  
   
endmodule

2、然後是接收

`timescale 1ns / 1ps


module rx(data_in,
          en,
          rx_finish,
          clk,
          data_out,
          rst
);
input data_in;
input clk,en,rst;//
output  rx_finish;
reg rx_finish;
output reg[7:0]  data_out;
reg[7:0] data_buffer;
reg[13:0] timer=0;
reg[7:0] time1=0;
reg[8:0] time2;
reg[3:0] i;  
(* KEEP =  "TRUE" *) reg  T=0;//前面括號是為了在chipscope中能找到改訊號,以免被優化掉




always @(posedge clk)//use for chipscope,chipscope的觸發訊號產生
begin
time1<=time1+1'd1;
if(time1==8'd121)
begin
time1<=0;
T<=!T;
end
end


always @(posedge clk)
begin
  if(rst)
    begin
      rx_finish<=0;
      data_out<=0;
      timer<=0;
      i<=0;
    end
     if(en)
     begin timer<=timer; end
     case (i)
         4'd0:
         begin


if(!data_in)
begin
rx_finish<=1'b1;//
if(timer==13'd217)//這個時間不能為433,多了會產生錯誤。由於是實驗所以中間只抽樣了一次,實際上stm32中有16或者8次抽樣
begin
i<=i+1'b1;
end 
  else
begin timer<=timer+1'b1;end//consuming remainder counter cycle
 end
          end
         4'd1:
             begin
               if(timer==13'd650)
                 begin               
                  data_buffer[0]<=data_in; 
                    timer<=timer+1'b1;
                end          
               else
                   timer<=timer+1'b1;
               if(timer==13'd867) begin i<=i+1'b1;end
             end     
          4'd2:
             begin
                if(timer==13'd1084)
                 begin
                    data_buffer[1]<=data_in;
                    timer<=timer+1'b1;
                end  
                else
                  timer<=timer+1'b1;
                 if(timer==13'd1301)  begin i<=i+1'b1;end
             end
         4'd3:
             begin
               if(timer==13'd1518)
                begin
                   data_buffer[2]<=data_in;
                    timer<=timer+1'b1;
                end  
            else
                timer<=timer+1'b1;
                if(timer==13'd1735)  begin i<=i+1'b1;end
            end
          4'd4:
           begin
                if(timer==13'd1952)
                begin
                   data_buffer[3]<=data_in;
                    timer<=timer+1'b1;
                end  
                else
                  timer<=timer+1'b1;
               if(timer==13'd2169) begin i<=i+1'b1;end
            end
          4'd5:
             begin
               if(timer==13'd2386)
                begin
                   data_buffer[4]<=data_in;
                   timer<=timer+1'b1;
                end  
               else
               timer<=timer+1'b1;
               if(timer==13'd2603) begin i<=i+1'b1;end
            end
          4'd6:
             begin
               if(timer==13'd2820)
                begin
                    data_buffer[5]<=data_in;
                    timer<=timer+1'b1;
               end  
               else
                   timer<=timer+1'b1;
                if(timer==13'd3037)  begin i<=i+1'b1;end
            end
          4'd7:
            begin
                if(timer==13'd3254)
                begin
                   data_buffer[6]<=data_in;
                   timer<=timer+1'b1;
               end  
               else
                   timer<=timer+1'b1;
               if(timer==13'd3471)  begin i<=i+1'b1;end
           end
         4'd8:
            begin
               if(timer==13'd3688)
                 begin
                   data_buffer[7]<=data_in;
                   timer<=timer+1'b1;
 
                 end  
               else
                 timer<=timer+1'b1; 
                 if(timer==13'd3905)  begin i<=i+1'b1;end
             end
         4'd9:
         begin
              if(timer==13'd4339) 
              begin 
i<=i+1'd1;
 end
 else timer<=timer+1'd1;
end
         4'd10:
       begin
             if(timer==13'd4556)
             begin
                   if(data_in)  
                   begin
                      rx_finish<=0;//??ê?′?ê??áê?
                     timer<=timer+1'b1;
data_out<=data_buffer;
                   end
else
begin
 timer<=timer+1'b1;
i<=0;
timer<=0;
data_out<=8'b00001111;
end
                 end   
             else
              timer<=timer+1'b1;
 
 
             if(timer==13'd4773)  
begin 
i<=0;
timer<=0;//c<=0;
               data_buffer<=8'b00001111;
end
        
          end
     endcase  
// data_out<=data_buffer;
   // end


end


endmodule

3、最後是例項化

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    13:35:14 04/20/2017 
// Design Name: 
// Module Name:    top 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 例項化
//
//////////////////////////////////////////////////////////////////////////////////
module top(in_data,
  out_data,
  clk,
  rx_finish,
  en_rx,
  en_tx,
  rst
    );
input in_data,clk,rst,en_rx,en_tx;//
output out_data,rx_finish;//
wire[7:0] data_bus;
//wire rxf;


send u1(.in_data(data_bus),.out_data(out_data),.en(en_tx),.clk(clk));
rx   u2(.data_in(in_data),.rx_finish(rxf),.clk(clk),.data_out(data_bus),.en(en_rx),.rst(rst));//


endmodule

4、總結

(1)、調串列埠我是先調的發射,再將兩個程式合在一起調。雖然在調發射的沒經過多大的周折,導致粗心大意在,
使得調接受的時候用modelsim模擬過了就直接將兩個程式合再一起了。以後要注意,每次調程式每個模組都除錯通過才能合再一起

(2)、再將兩個程式合再一起出現了問題,但找問題時還是要分開找問題,不要兩個程式合在一起找問題

(3)、在例化時,比如.en(en)點後面的是外部的,括號裡頭的是當前模組申明的en

5、存留問題,還沒想明白

         4'd0:
         begin


if(!data_in)
begin
rx_finish<=1'b1;//胡  
if(timer==13'd217)
begin
i<=i+1'b1;
end 
  else
begin timer<=timer+1'b1;end//consuming remainder counter cycle
 end
          end

之前timer==13'd433時有問題,而且花了很長時間找到這個問題

比如發0x99  有時收到0xcc  發0x01 有時收到0x80