www.pudn.com > 1553B_enc_dec.rar > decoder_1553.v, change:2011-09-14,size:6837b


// ============================================================================= 
//                           COPYRIGHT NOTICE 
// Copyright 2004 (c) by Lattice Semiconductor Corporation 
// 
// Permission : 
//  
// Lattice Semiconductor grants permission to use this code for use in synthesis 
// for Lattice programmable logic product. Other use of this code, including  
// the selling or duplication of any portion ia strictly prohibited. 
//  
// Disclaimer : 
// 
// This VHDL or Verilog source code is intended as a design reference which 
// illustrares how these types of functions can be implemeted. It is the  
// user's responsibility to verify their design for consistency and  
// functionality through the use of suitable verification methods.  
// Lattice Semiconductor provides no waranty regarding the use or  
// functionality of this code.  
// ============================================================================= 
// 
//                     Lattice Semiconductor Corporation     
//                     5555 NE Moore Court                     
//                     Hillsboro, OR 97124                   
//                     U.S.A                                
// 
//                     TEL : 1-800-Lattice (USA and Canada) 
//                           408-826-6000 (other locations) 
//                     web  : http://www.latticesemi.com/ 
//                     email: techsupport@latticesemi.com 
// ============================================================================= 
// Project          : 1553_enc_dec 
// File             : decoder_1553.v 
// Title            : 
// Dependencies     :  
// Description      : This module implements 1553 decoding logic.  
//                    Detects transitions on serial input. 
//                    Detects sync patterns and data word boundaries. 
//                    De-serializes and generates parallel data word. 
//                    Checks parity. 
// ============================================================================= 
// REVISION HISTORY 
// Version          : 1.0 
// ============================================================================= 
 
module decoder_1553 ( 
            // Clock and Reset 
            dec_clk , 
            rst_n , 
 
            // Inputs 
            rx_data , 
 
            // Outputs 
            rx_dword ,  
            rx_dval ,  
            rx_csw , 
            rx_dw , 
            rx_perr 
            ) ; 
 
 
input          dec_clk ;   // 8Mhz decoder clock. 
input          rst_n ;     // Asynchronous reset. 
 
input          rx_data ;   // Serial transmit data input.  
 
output [0:15]  rx_dword ;  // Output data word receive. 
output         rx_dval ;   // Indicates data on "rx_data" is valid. 
output         rx_csw ;    // "rx_dword" has command or status word. 
output         rx_dw ;     // "rx_dword" has data word. 
output         rx_perr ;   // Indicates parity error in "rx_dword". 
 
reg [0:15]     rx_dword ; 
reg            rx_dval ; 
reg            rx_csw ; 
reg            rx_dw ; 
reg            rx_perr ; 
 
reg [0:23]     sync_sftreg ; 
reg [0:4]      data_sftreg ; 
reg            cnt_enb ; 
reg [7:0]      cnt ; 
reg [0:16]     dword_int ; 
reg            sync_csw_reg ; 
reg            sync_dw_reg ; 
 
wire           sync_edge ; 
wire           data_edge ; 
wire           sync_csw ; 
wire           sync_dw ; 
wire           data_sample ; 
wire           parity ; 
 
 
// Shift in the serial data through shift registrs. 
always @(posedge dec_clk or negedge rst_n) begin 
   if (!rst_n ) begin    
      data_sftreg <= 5'd0 ; 
      sync_sftreg <= 24'd0 ; 
   end 
   else  begin  
      data_sftreg <= {data_sftreg[1:4],rx_data} ; 
      sync_sftreg <= {sync_sftreg[1:23],data_sftreg[0]} ; 
   end 
end 
 
 
// Detect transitions. 
assign data_edge =  data_sftreg[3] ^ data_sftreg[4] ; 
 
// Detect sync pattern for command and status word 
assign sync_csw = (sync_sftreg == 24'hFFF_000) & data_edge ; 
 
// Detect sync pattern for data word 
assign sync_dw =  (sync_sftreg == 24'h000_FFF) & data_edge ;  
 
// Count number of clocks to get complete word after  
// detecting the sync pattern 
always @(posedge dec_clk or negedge rst_n) begin 
   if (!rst_n )     
      cnt_enb <= 1'b0 ; 
   else if (sync_csw || sync_dw) 
      cnt_enb <= 1'b1 ; 
   else if (cnt == 'd131) 
      cnt_enb <= 1'b0 ; 
   else  
      cnt_enb <= cnt_enb ; 
end 
 
always @(posedge dec_clk or negedge rst_n) begin 
   if (!rst_n )     
      cnt <= 8'hFF ;     //256 
   else if (cnt_enb) 
      cnt <= cnt + 1 ;     //最大值为132 
   else if (!cnt_enb) 
      cnt <= 8'hFF ; 
   else  
      cnt <= cnt ; 
end 
 
// Generate data sample points. 
//cnt[2:0] = 'b000, 即每隔8次采样一次,132计数中共采样17次, 
assign data_sample =  (~cnt[2] & ~cnt[1] & ~cnt[0]) ; 
 
// register data at every sample point through shift register. 
always @(posedge dec_clk or negedge rst_n) begin 
   if (!rst_n )     
      dword_int <= 17'h0000 ;                        
   else if (data_sample && cnt_enb)   //在每一个曼码变化电平边沿后两个dec_clk周期进行采样,这样1对应曼码“0”,0对应曼码“1”,取反即可解码 
      dword_int <= {dword_int[1:16],~data_sftreg[2]} ;   //每一次都检测data_sftreg[2], 保证数据稳定,在两个dec_clk之后,进行解码 
   else if (!cnt_enb) 
      dword_int <= 17'h0000 ; 
   else  
      dword_int <= dword_int ; 
end 
 
// Register command and status sync patter type till the end  
// of data word. 
always @(posedge dec_clk or negedge rst_n) begin 
   if (!rst_n )     
      sync_csw_reg <= 1'b0 ; 
   else if (sync_csw) 
      sync_csw_reg <= 1'b1 ; 
   else if (cnt == 'd132) 
      sync_csw_reg <= 1'b0 ; 
   else  
      sync_csw_reg <= sync_csw_reg ; 
end 
 
// Register data sync patter type till the end of data word. 
always @(posedge dec_clk or negedge rst_n) begin 
   if (!rst_n )     
      sync_dw_reg <= 1'b0 ; 
   else if (sync_dw) 
      sync_dw_reg <= 1'b1 ; 
   else if (cnt == 'd132) 
      sync_dw_reg <= 1'b0 ; 
   else  
      sync_dw_reg <= sync_dw_reg ; 
end 
 
// Register the parallel data word and control outputs. 
always @(posedge dec_clk or negedge rst_n) begin 
   if (!rst_n ) begin     
      rx_dword <= 16'h0000 ; 
      rx_dval  <= 1'b0 ; 
      rx_perr  <= 1'b0 ; 
      rx_csw   <= 1'b0 ; 
      rx_dw    <= 1'b0 ; 
   end 
   else if (cnt == 'd131) begin 
      rx_dword <= dword_int[0:15] ; 
      rx_dval  <= 1'b1 ; 
      rx_perr  <= ((^dword_int[0:15]) != dword_int[16]) ; 
      rx_csw   <= sync_csw_reg ; 
      rx_dw    <= sync_dw_reg ; 
   end 
   else  begin 
      rx_dword <= 16'h0000 ; 
      rx_dval  <= 1'b0 ; 
      rx_perr  <= 1'b0 ; 
      rx_csw   <= 1'b0 ; 
      rx_dw    <= 1'b0 ; 
   end 
end 
 
endmodule 
// =============================================================================