//+FHDR--------------------------------------------------------------------------------------------------------
//  Company: 
//-----------------------------------------------------------------------------------------------------------------
//  File Name             :    ssytem_regfile.v
//  Department            :    
//  Author                :    PWY
//  Author's Tel          :     
//-----------------------------------------------------------------------------------------------------------------
//  Relese History
//  Version     Date            Author          Description
//  1.0         2026-03-01      PWY
//-----------------------------------------------------------------------------------------------------------------
//  Keywords            :       
//
//-----------------------------------------------------------------------------------------------------------------
//  Parameter
//
//-----------------------------------------------------------------------------------------------------------------
//  Purpose                 :
//                      
//-----------------------------------------------------------------------------------------------------------------
//  Target Device:        
//  Tool versions:        
//-----------------------------------------------------------------------------------------------------------------
//  Reuse Issues
//  Reset Strategy: 
//  Clock Domains: 
//  Critical Timing:
//  Asynchronous I/F:
//  Synthesizable (y/n): 
//  Other:
//-FHDR--------------------------------------------------------------------------------------------------------

// -----------------------------------------------------------
// -- Register address offset macros
// -----------------------------------------------------------
//Identity Register
`define IDR      16'h00
//Vendor Code Register
`define VIDR     16'h04
//RTL Freeze Date Register
`define DATER    16'h08
//Version Register
`define VERR     16'h0C
//Wirte And Read Test Register
`define TESTR    16'h10
//Status Register
`define ISR      16'h14
//Soft Reset Time Register
`define SFRTR    16'h18
//Soft Reset Register
`define SFRR     16'h1C
//Sync Cntrl Register
`define SYNCR    16'h20
//Ramp Ctrl Register
`define RAMPCTR  16'h24
//Ramp IFS Register
`define RAMPIFSR 16'h28
//Data Out Select Register
`define DOSELR   16'h2C
//Lvds Force Train Register
`define LVDSFTR  16'h30
//Lvds Tap Force Register
`define LVDSTFR  16'h34
//Lvds Tap Step Register
`define LVDSTSR  16'h38
//Lvds Train Threshold Register
`define LVDSTHR  16'h3C
//Lvds Tap Adj Mask Register
`define LVDSTAMR 16'h40
//Lvds Descram Enable Register
`define LVDSDSER 16'h44
//Lvds Train Always On Register
`define LVDSTAOR 16'h48
//Lvds Status Register
`define LVDSSR   16'h4C
//Lvds Frame Success Count Register
`define LVDSFSCR 16'h50
//Lvds CRC Error Count Register
`define LVDSCECR 16'h54
//Lvds Frame Status Register
`define LVDSFSTR 16'h58
//Lvds Train Status Register
`define LVDSTSTR 16'h5C

//Interrupt Mask Register
//[31 :6] --> Reserved 
//[5    ] --> crc_error      Interrupt Mask
//[4    ] --> phase_adj_req  Interrupt Mask
//[3    ] --> train_ready    Interrupt Mask
//[2    ] --> link_down      Interrupt Mask
//[1    ] --> cmd_fifo_empty Interrupt Mask
//[0    ] --> cmd_fifo_full  Interrupt Mask
`define IMR   16'h60

//Interrupt Mask Register
//[31 :6] --> Reserved   
//[5    ] --> crc_error       Masked Interrupt Status
//[4    ] --> phase_adj_req   Masked Interrupt Status
//[3    ] --> train_ready     Masked Interrupt Status
//[2    ] --> link_down       Masked Interrupt Status
//[1    ] --> cmd_fifo_empty  Masked Interrupt Status
//[0    ] --> cmd_fifo_full   Masked Interrupt Status
`define MISR   16'h64

module systemregfile # (
   parameter CHIPCODE =  32'hDA400801  // 32'hDA400801:DA4008-01
  ,parameter MFDATE   =  32'h20260510  // The production date is May 10, 2026
  )(
  //system port
   input          clk             // System Main Clock
  ,input          rst_n            // Spi Reset active low
  //rw op port
  ,input  [31 :0] wrdata          // write data
  ,input          wren            // write enable
  ,input  [15 :0] rwaddr          // read & write address
  ,input          rden            // read enable
  ,output [31 :0] rddata          // read data
  //irq
  ,output         irq
  //Status input
  ,input          cmd_fifo_full
  ,input          cmd_fifo_empty
  ,input  [2  :0] awg_status
  ,input          awg_busy
  //Soft Reset out
  ,output         sys_soft_rstn    
  //Data Out Select port
  ,output [0  :0] dout_sel      //1'b0: Sram Data; 1'b1: Ramp Data; 
  //SYNC Ctrl
  ,output [15 :0] sync_delay 
  ,output         int_sync   
  ,output         int_sync_en
  ,output         sync_oen
  //Ramp Cntrl Signals
  ,output         ramp_en        //ramp_en = dout_sel[0]; 
  ,output [31 :0] ramp_ifs
  ,output [7  :0] ramp_step
  ,output         ramp_fixed
  ,output [7  :0] ramp_fixed_value
  //LVDS
  ,output         force_train        
  ,output         tap_force         
  ,output [2  :0] tap_step  
  ,output [2  :0] tap_adj_mask  
  ,output [19 :0] train_threshold 
  ,output         descram_en
  ,output         always_on 
  ,input          link_down
  ,input          train_ready         
  ,input          crc_error         
  ,input          phase_adj_req     
  ,input [2  :0]  phase_tap                         
  ,input [31 :0]  frame_success_cnt   
  ,input [31 :0]  crc_err_cnt       
  ,input          prefilling  
  ,input [31 :0]  train_status
  ,input [31 :0]  frame_status
);

localparam L = 1'b0,
           H = 1'b1;
                   
localparam IDRD    = CHIPCODE;
localparam VIDRD   = 32'h58445500;        
localparam DATERD  = MFDATE;
localparam VERSION = 32'h00000001;      
localparam TESTRD  = 32'h01234567;       
// ------------------------------------------------------
// -- Register enable (select) wires
// ------------------------------------------------------
wire  idren        ;    // IDR      select
wire  vidren       ;    // VIDR     select
wire  dateren      ;    // DATER    select
wire  verren       ;    // VERR     select
wire  testren      ;    // TESTR    select
wire  isren        ;    // ISR      select
wire  sfrtren      ;    // MISR     select
wire  sfrren       ;    // SFRTR    select
wire  syncren      ;    // SFRR     select
wire  rampctren    ;    // RAMPCTR  select
wire  rampifsren   ;    // RAMPIFSR select
wire  doselren     ;    // DOSELR   select
wire  lvdsftren    ;    // LVDSFTR  select
wire  lvdstfren    ;    // LVDSTFR  select
wire  lvdstsren    ;    // LVDSTSR  select
wire  lvdsthren    ;    // LVDSTHR  select
wire  lvdssren     ;    // LVDSSR   select
wire  lvdsfcsren   ;    // LVDSFSCR select
wire  lvdscecren   ;    // LVDSCECR select
wire  lvdstamren   ;    // LVDSTAMR select
wire  lvdsdseren   ;    // LVDSDSER select
wire  lvdstaoren   ;    // LVDSTAOR select
wire  lvdsfstren   ;    // LVDSFSTR select
wire  lvdststren   ;    // LVDSTSTR select  
wire  imren        ;    // IMR      select
wire  misren       ;    // MISR     select
// ------------------------------------------------------
// -- Register write enable wires
// ------------------------------------------------------
wire  testrwe       ;    // testr    write enable
wire  sfrtrwe       ;    // sfrtr    write enable
wire  sfrrwe        ;    // sfrr     write enable
wire  syncrwe       ;    // syncr    write enable
wire  rampctrwe     ;    // RAMPCTR  write enable
wire  rampifsrwe    ;    // RAMPIFSR write enable
wire  doselrwe      ;    // DOSELR   write enable
wire  lvdsftrwe     ;    // LVDSFTR  write enable
wire  lvdsatrwe     ;    // LVDSATR  write enable
wire  lvdstsrwe     ;    // LVDSTSR  write enable
wire  lvdsthrwe     ;    // LVDSTHR  write enable
wire  lvdsdserwe    ;    // LVDSDSER  write enable
wire  lvdstaorwe    ;    // LVDSTAOR  write enable
wire  imrwe         ;    // IMR      write enable
// ------------------------------------------------------
// -- Misc wires
// ------------------------------------------------------
wire [5 :0] irisr    ;  // original status wire 

// ------------------------------------------------------
// -- Misc Registers
// ------------------------------------------------------
wire  [31 :0] testr       ;
wire  [5  :0] isr         ;
wire  [31 :0] sfrtr       ;
wire  [0  :0] sfrr        ;
wire  [18 :0] syncr       ;
wire  [23 :0] rampctr     ;    
wire  [31 :0] rampifsr    ;    
wire  [0  :0] doselr      ;    

wire  [0  :0] lvdsftr     ;    
wire  [0  :0] lvdsatr     ;    
wire  [2  :0] lvdstsr     ;    
wire  [19 :0] lvdsthr     ;    
wire  [7  :0] lvdssr      ;    
wire  [31 :0] lvdsfcsr    ;      
wire  [31 :0] lvdscecr    ; 
wire  [2  :0] lvdstamr    ;    
wire  [0  :0] lvdsdser    ; 
wire  [0  :0] lvdstaor    ;  
wire  [31 :0] lvdsfstr    ;   
wire  [31 :0] lvdststr    ; 
wire  [5  :0] imr         ;    
wire  [5  :0] misr        ;    
                                    
reg   [31 :0] rddata_reg  ;
                                    
// ------------------------------------------------------
// -- Address decoder
//
//  Decodes the register address offset input(reg_addr)
//  to produce enable (select) signals for each of the
//  SW-registers in the macrocell. The reg_addr input
//  is bits [8:0] of the paddr bus. 
// ------------------------------------------------------
assign idren      = (rwaddr[15:2] == `IDR      >> 2) ? 1'b1 : 1'b0;
assign vidren     = (rwaddr[15:2] == `VIDR     >> 2) ? 1'b1 : 1'b0;
assign dateren    = (rwaddr[15:2] == `DATER    >> 2) ? 1'b1 : 1'b0;
assign verren     = (rwaddr[15:2] == `VERR     >> 2) ? 1'b1 : 1'b0;
assign testren    = (rwaddr[15:2] == `TESTR    >> 2) ? 1'b1 : 1'b0;
assign isren      = (rwaddr[15:2] == `ISR      >> 2) ? 1'b1 : 1'b0;
assign sfrtren    = (rwaddr[15:2] == `SFRTR    >> 2) ? 1'b1 : 1'b0;
assign sfrren     = (rwaddr[15:2] == `SFRR     >> 2) ? 1'b1 : 1'b0;
assign syncren    = (rwaddr[15:2] == `SYNCR    >> 2) ? 1'b1 : 1'b0;
assign rampctren  = (rwaddr[15:2] == `RAMPCTR  >> 2) ? 1'b1 : 1'b0;
assign rampifsren = (rwaddr[15:2] == `RAMPIFSR >> 2) ? 1'b1 : 1'b0;
assign doselren   = (rwaddr[15:2] == `DOSELR   >> 2) ? 1'b1 : 1'b0;
assign lvdsftren  = (rwaddr[15:2] == `LVDSFTR  >> 2) ? 1'b1 : 1'b0;
assign lvdstfren  = (rwaddr[15:2] == `LVDSTFR  >> 2) ? 1'b1 : 1'b0;
assign lvdstsren  = (rwaddr[15:2] == `LVDSTSR  >> 2) ? 1'b1 : 1'b0;
assign lvdsthren  = (rwaddr[15:2] == `LVDSTHR  >> 2) ? 1'b1 : 1'b0;
assign lvdssren   = (rwaddr[15:2] == `LVDSSR   >> 2) ? 1'b1 : 1'b0;
assign lvdsfcsren = (rwaddr[15:2] == `LVDSFSCR >> 2) ? 1'b1 : 1'b0;
assign lvdscecren = (rwaddr[15:2] == `LVDSCECR >> 2) ? 1'b1 : 1'b0;
assign lvdstamren = (rwaddr[15:2] == `LVDSTAMR >> 2) ? 1'b1 : 1'b0;
assign lvdsdseren = (rwaddr[15:2] == `LVDSDSER >> 2) ? 1'b1 : 1'b0;
assign lvdstaoren = (rwaddr[15:2] == `LVDSTAOR >> 2) ? 1'b1 : 1'b0;
assign lvdsfstren = (rwaddr[15:2] == `LVDSFSTR >> 2) ? 1'b1 : 1'b0;
assign lvdststren = (rwaddr[15:2] == `LVDSTSTR >> 2) ? 1'b1 : 1'b0;
assign imren      = (rwaddr[15:2] == `IMR      >> 2) ? 1'b1 : 1'b0;
assign misren     = (rwaddr[15:2] == `MISR     >> 2) ? 1'b1 : 1'b0;
// ------------------------------------------------------
// -- Write enable signals
//
//  Write enable signals for writable SW-registers.
//  The write enable for each register is the ANDed
//  result of the register enable and the input reg_wren
// ------------------------------------------------------ 
assign testrwe     = testren    &  wren;
assign sfrtrwe     = sfrtren    &  wren;
assign sfrrwe      = sfrren     &  wren;
assign syncrwe     = syncren    &  wren;
assign rampctrwe   = rampctren  &  wren;
assign rampifsrwe  = rampifsren &  wren;
assign doselrwe    = doselren   &  wren;
assign lvdsftrwe   = lvdsftren  &  wren;    
assign lvdstfrwe   = lvdstfren  &  wren;    
assign vdstsrwe    = lvdstsren  &  wren;    
assign lvdsthrwe   = lvdsthren  &  wren; 
assign lvdstamrwe  = lvdstamren &  wren; 
assign lvdsdserwe  = lvdstamren &  wren; 

assign imrwe       = imren      &  wren; 
  
// ------------------------------------------------------
// -- testr Register
//
//  Write testr for 'TESTR' : 32-bit register
//  Register is split into the following bit fields
//
//  [31:0] --> testr 
// ------------------------------------------------------
sirv_gnrl_dfflrd #(32) testr_dfflrd (TESTRD, testrwe, wrdata[31:0], testr, clk, rst_n);


// ------------------------------------------------------
// -- Soft Reset Count Register
//
//  Write Soft Reset Count for 'sfrtcr' : 6-bit register
//  Register is split into the following bit fields
//
//  [31:0]    --> sfrtcr,default value 32'd300  
// ------------------------------------------------------
sirv_gnrl_dfflrd #(32) sfrtr_dfflrd (32'd1, sfrtrwe, wrdata[31:0], sfrtr, clk, rst_n);/////////////////////////////sfrtcr-->sfrtr


// ------------------------------------------------------
// -- SYNC Contrl Register
//
//
//  [17  ]    --> sync_oen   ,default value 1'b0 
//  [17  ]    --> int_sync_en,default value 1'b0  
//  [16  ]    --> int_sync   ,default value 1'b0  
//  [15:0]    --> sync_delay ,default value 16'd0  
// ------------------------------------------------------
//sirv_gnrl_dfflr #(18) syncr_dfflr (syncrwe, wrdata[17:0], syncr, clk, rst_n);
// sirv_gnrl_dfflr #(17) syncr_dfflr (syncrwe, {syncrwe,wrdata[15:0]}, syncr, clk, rst_n); //pwy-20250808
sirv_gnrl_dfflrd #(16) syncr_dfflrd (16'd1, syncrwe, wrdata[15:0], syncr[15:0], clk, rst_n); //pwy-20250808
sirv_gnrl_dffr #(1) syncr16_dffr (syncrwe & wrdata[16], syncr[16], clk, rst_n); //pwy-20250808
sirv_gnrl_dfflrd #(1) syncr16_dfflrd (1'b1, syncrwe, wrdata[17], syncr[17], clk, rst_n); //pwy-20250808
sirv_gnrl_dfflrd #(1) sync_oen_dfflrd (1'b0, syncrwe, wrdata[18], syncr[18], clk, rst_n); //pwy-20260303
// ------------------------------------------------------
// -- rampctr register
//
//  Write rampctr for 'RAMPCTR' : 24-bit register
//  Register is split into the following bit fields
//
//  [23:0] --> rampctr 
// ------------------------------------------------------
sirv_gnrl_dfflr #(24) rampctr_dfflrs (rampctrwe, wrdata[23:0], rampctr, clk, rst_n);

// ------------------------------------------------------
// -- rampifsr register
//
//  Write rampifsr for 'rampifsr' : 32-bit register
//  Register is split into the following bit fields
//
//  [31:0] --> ramp_ifs 
// ------------------------------------------------------
sirv_gnrl_dfflr #(32) ramp_ifs_dfflrs (rampifsrwe, wrdata[31:0], rampifsr, clk, rst_n);

// ------------------------------------------------------
// -- doselr register
//
//  Write doselr for 'DOSELR' : 1-bit register
//  Register is split into the following bit fields
//
//  [0:0] --> doselr 
// ------------------------------------------------------
sirv_gnrl_dfflr #(1) doselr_dfflrs (doselrwe, wrdata[0], doselr, clk, rst_n);

// ------------------------------------------------------
// -- lvdsftr Register
//
//  Write lvdsftr for 'LVDSFTR' : 1-bit register
//  Register is split into the following bit fields
//
//  [0:0] --> lvdsftr 
// ------------------------------------------------------
sirv_gnrl_dffr #(1) lvdsftr_dffr (lvdsftrwe & wrdata[0], lvdsftr, clk, rst_n); 

// ------------------------------------------------------
// -- lvdstfr register
//
//  Write lvdstfr for 'LVDSTFR' : 1-bit register
//  Register is split into the following bit fields
//
//  [0:0] --> lvdstfr 
// ------------------------------------------------------
sirv_gnrl_dfflr #(1) lvdstfr_dfflrs (lvdstfrwe, wrdata[0], lvdstfr, clk, rst_n);

// ------------------------------------------------------
// -- lvdstsr register
//
//  Write lvdstsr for 'LVDSTSR' : 1-bit register
//  Register is split into the following bit fields
//
//  [2:0] --> lvdstsr 
// ------------------------------------------------------
sirv_gnrl_dfflrd #(3) lvdstsr_dfflrd (3'd1, lvdstsrwe, wrdata[2:0], lvdstsr, clk, rst_n); 

// ------------------------------------------------------
// -- lvdsthr register
//
//  Write lvdsthr for 'LVDSTHR' : 20-bit register
//  Register is split into the following bit fields
//
//  [19:0] --> lvdsthr 
// ------------------------------------------------------
sirv_gnrl_dfflrd #(20) lvdsthr_dfflrd (20'd100, lvdsthrwe, wrdata[19:0], lvdsthr, clk, rst_n); 

// ------------------------------------------------------
// -- lvdstamr register
//
//  Write lvdsfcsr for 'LVDSTAMR' : 3-bit register
//  Register is split into the following bit fields
//
//  [2:0] --> lvdstamr 
// ------------------------------------------------------
sirv_gnrl_dfflrd #(3) lvdstamr_dfflrd (3'b111, lvdstamrwe, wrdata[2:0], lvdstamr, clk, rst_n);
 
// ------------------------------------------------------
// -- lvdsdser register
//
//  Write lvdsfcsr for 'LVDSDSER' : 1-bit register
//  Register is split into the following bit fields
//
//  [0:0] --> lvdsdser 
// ------------------------------------------------------
sirv_gnrl_dfflrd #(1) lvdsdser_dfflrd (1'b1, lvdsdserwe, wrdata[0], lvdsdser, clk, rst_n); 


// ------------------------------------------------------
// -- lvdstaor register
//
//  Write lvdstaor for 'LVDSTAOR' : 1-bit register
//  Register is split into the following bit fields
//
//  [0:0] --> lvdstaor 
// ------------------------------------------------------
sirv_gnrl_dfflrd #(1) lvdstaor_dfflrd (1'b1, lvdstaorwe, wrdata[0], lvdstaor, clk, rst_n); 
 
// ------------------------------------------------------
// -- lvdssr register
//
//  Write lvdssr for 'LVDSSR' : 8-bit register
//  Register is split into the following bit fields
//
//  [7:0] --> lvdssr 
// ------------------------------------------------------
sirv_gnrl_dffr #(8) llvdssr_dffr ({ link_down ,train_ready    ,crc_error  ,
                                     phase_adj_req   ,phase_tap[2:0] ,
									 prefilling  }, lvdssr, clk, rst_n); 

// ------------------------------------------------------
// -- lvdsfcsr register
//
//  Write lvdsfcsr for 'LVDSFSCR' : 32-bit register
//  Register is split into the following bit fields
//
//  [31:0] --> lvdsfcsr 
// ------------------------------------------------------
sirv_gnrl_dffr #(32) lvdsfcsr_dffr (frame_success_cnt, lvdsfcsr, clk, rst_n); 
 

// ------------------------------------------------------
// -- lvdscecr register
//
//  Write lvdscecr for 'LVDSCECR' : 32-bit register
//  Register is split into the following bit fields
//
//  [31:0] --> lvdscecr 
// ------------------------------------------------------
sirv_gnrl_dffr #(32) lvdscecr_dffr (crc_err_cnt, lvdscecr, clk, rst_n); 

// ------------------------------------------------------
// -- lvdsfstr register
//
//  Write lvdsfstr for 'LVDSFSR' : 32-bit register
//  Register is split into the following bit fields
//
//  [31:0] --> lvdsfstr 
// ------------------------------------------------------
sirv_gnrl_dffr #(32) lvdsfstr_dffr (frame_status, lvdsfstr, clk, rst_n); 

// ------------------------------------------------------
// -- lvdststr register
//
//  Write lvdststr for 'LVDTFSR' : 32-bit register
//  Register is split into the following bit fields
//
//  [31:0] --> lvdststr 
// ------------------------------------------------------
sirv_gnrl_dffr #(32) lvdststr_dffr (train_status, lvdststr, clk, rst_n); 

// ---------------------------------------------------------------------------------------------------
// -- interrupt Mask Register
//
//  Write interrupt Mask for 'imr' : 6-bit register
//  Register is split into the following bit fields
//
//Interrupt Mask Register
//[31 :6] --> Reserved 
//[5    ] --> crc_error      Interrupt Mask
//[4    ] --> phase_adj_req  Interrupt Mask
//[3    ] --> train_ready    Interrupt Mask
//[2    ] --> link_down      Interrupt Mask
//[1    ] --> cmd_fifo_empty Interrupt Mask
//[0    ] --> cmd_fifo_full  Interrupt Mask
// ---------------------------------------------------------------------------------------------------
sirv_gnrl_dfflr #(6) imr_dfflr (imrwe, wrdata[5:0], imr, clk, rst_n);
									
// ------------------------------------------------------
// -- soft reset count
// ------------------------------------------------------  

wire [31:0] cnt_c;
wire        sys_soft_rstn_r;
wire add_cnt = (sys_soft_rstn_r == L) ;
                           
wire end_cnt = add_cnt & (cnt_c == sfrtr-1);

wire [31:0] cnt_n = end_cnt ? 32'h0        :
                    add_cnt ? cnt_c + 1'b1 :
                              cnt_c        ;


sirv_gnrl_dffr #(32) cnt_c_dffr (cnt_n, cnt_c, clk, rst_n); 

// ------------------------------------------------------
// -- Soft Reset Register
//
//  Write Soft Reset for 'sfrtr' : 1-bit register
//  Register is split into the following bit fields
//
//  [16'h001C]    --> System Soft Reset  ,low active
// ------------------------------------------------------

//sys_soft_rstn_r
wire sys_soft_rstn_en = end_cnt | sfrrwe;
wire sys_soft_rstn_w  = end_cnt ? 1'b1 :
                        sfrrwe  ? 1'b0 :
                                  1'b1 ;
sirv_gnrl_dfflrs #(1) sys_soft_rstn_r_dffls (sys_soft_rstn_en, sys_soft_rstn_w, sys_soft_rstn_r, clk, rst_n);

assign  sys_soft_rstn = sys_soft_rstn_r;


// ------------------------------------------------------
// -- Read data mux
//
// -- The data from the selected register is
// -- placed on a zero-padded 32-bit read data bus.
// ------------------------------------------------------
always @(*) begin : RDDATA_PROC
  rddata_reg = {32{1'b0}};
  if(idren      == H)    rddata_reg[31:0] = IDRD     ;
  if(vidren     == H)    rddata_reg[31:0] = VIDRD    ;
  if(dateren    == H)    rddata_reg[31:0] = DATERD   ;
  if(verren     == H)    rddata_reg[31:0] = VERSION  ;
  if(testren    == H)    rddata_reg[31:0] = testr    ;
  if(isren      == H)    rddata_reg[31:0] = isr      ;
  if(sfrtren    == H)    rddata_reg[31:0] = sfrtr    ;
  if(syncren    == H)    rddata_reg[18:0] = syncr    ;
  if(rampctren  == H)    rddata_reg[23:0] = rampctr  ;
  if(rampifsren == H)    rddata_reg[31:0] = rampifsr ;
  if(doselren   == H)    rddata_reg[0 :0] = doselr   ;
  if(lvdsftren  == H)    rddata_reg[0 :0] = lvdsftr  ;
  if(lvdstfren  == H)    rddata_reg[0 :0] = lvdstfr  ;
  if(lvdstsren  == H)    rddata_reg[2 :0] = lvdstsr  ;
  if(lvdsthren  == H)    rddata_reg[19:0] = lvdsthr  ;
  if(lvdssren   == H)    rddata_reg[7 :0] = lvdssr   ;
  if(lvdstamren == H)    rddata_reg[2 :0] = lvdstamr ;
  if(lvdsfcsren == H)    rddata_reg[31:0] = lvdsfcsr ;
  if(lvdscecren == H)    rddata_reg[31:0] = lvdscecr ;
  if(lvdsdseren == H)    rddata_reg[0 :0] = lvdsdser ;
  if(lvdstaoren == H)    rddata_reg[0 :0] = lvdstaor ;
  if(lvdsfstren == H)    rddata_reg[31:0] = lvdsfstr ;
  if(lvdststren == H)    rddata_reg[31:0] = lvdststr ;
  if(imren      == H)    rddata_reg[5 :0] = imr      ;
  if(misren     == H)    rddata_reg[5 :0] = misr     ;
end

//rddata
sirv_gnrl_dfflr #(32) rddata_dfflr (rden, rddata_reg, rddata, clk, rst_n);

// ------------------------------------------------------
// -- status  
// ------------------------------------------------------
//read misr clear interrupts
wire icr = (misren) && rden;

//train_ready
wire train_ready_r;
wire train_ready_en = icr | train_ready;
wire train_ready_w = ~icr | train_ready;
sirv_gnrl_dfflr #(1) train_ready_r_dfflr (train_ready_en, train_ready_w, train_ready_r, clk, rst_n);

//crc_error
wire crc_error_r;
wire crc_error_en = icr | crc_error;
wire crc_error_w = ~icr | crc_error;
sirv_gnrl_dfflr #(1) crc_error_r_dfflr (crc_error_en, crc_error_w, crc_error_r, clk, rst_n);

//phase_adj_req
wire phase_adj_req_r;
wire phase_adj_req_en = icr | phase_adj_req;
wire phase_adj_req_w = ~icr | phase_adj_req;
sirv_gnrl_dfflr #(1) cphase_adj_req_r_dfflr (phase_adj_req_en, phase_adj_req_w, phase_adj_req_r, clk, rst_n);

//link_down
wire link_down_r;
wire link_down_en = icr | link_down;
wire link_down_w = ~icr | link_down;
sirv_gnrl_dfflr #(1) link_down_r_dfflr (link_down_en, link_down_w, link_down_r, clk, rst_n);

//cmd_fifo_full
wire cmd_fifo_full_r;
wire cmd_fifo_full_en = icr | cmd_fifo_full;
wire cmd_fifo_full_w = ~icr | cmd_fifo_full;
sirv_gnrl_dfflr #(1) cmd_fifo_full_r_dfflr (cmd_fifo_full_en, cmd_fifo_full_w, cmd_fifo_full_r, clk, rst_n);

//cmd_fifo_empty
wire cmd_fifo_empty_r;
wire cmd_fifo_empty_en = icr | cmd_fifo_empty;
wire cmd_fifo_empty_w = ~icr | cmd_fifo_empty;
sirv_gnrl_dfflr #(1) cmd_fifo_empty_r_dfflr (cmd_fifo_empty_en, cmd_fifo_empty_w, cmd_fifo_empty_r, clk, rst_n);

//irisr
//Interrupt Status Register
//[31 :6] --> Reserved 
//[5    ] --> crc_error      Interrupt Status
//[4    ] --> phase_adj_req  Interrupt Status
//[3    ] --> train_ready    Interrupt Status
//[2    ] --> link_down      Interrupt Status
//[1    ] --> cmd_fifo_empty Interrupt Status
//[0    ] --> cmd_fifo_full  Interrupt Status

assign irisr[5 ] = crc_error_r       ;
assign irisr[4 ] = phase_adj_req_r   ;
assign irisr[3 ] = train_ready_r     ;
assign irisr[2 ] = link_down_r       ;
assign irisr[1 ] = cmd_fifo_full_r   ;
assign irisr[0 ] = cmd_fifo_empty_r  ;

// ------------------------------------------------------
// -- Interrupt Status Register - Read Only
//
//  This register contains the status of all
//  DA4008 Chip interrupts after masking.
// ------------------------------------------------------
sirv_gnrl_dffr #(6) isr_dffr (irisr, isr, clk, rst_n);

//misr
wire[5:0] misr_w = imr & irisr;
sirv_gnrl_dffr #(6) misr_dffr (misr_w, misr, clk, rst_n);

//irq
wire irq_w = |misr;
sirv_gnrl_dffr #(1) irq_dffr (irq_w, irq, clk, rst_n);


//sync ctrl
assign sync_oen        = syncr[18  ] ;
assign int_sync_en     = syncr[17  ] ;
assign int_sync        = syncr[16  ] ;
assign sync_delay      = syncr[15:0] ;

//Ramp & Data Select
//Data Select
assign dout_sel             = doselr          ;
//RAMP cfg   
assign ramp_en              = doselr          ;
assign ramp_step            = rampctr[23:16]  ;
assign ramp_fixed_value     = rampctr[15:8]   ;
assign ramp_fixed           = rampctr[0]      ;
assign ramp_ifs             = rampifsr        ;

//LVDS
assign force_train          = lvdsftr ;        
assign tap_force            = lvdstfr ; 
assign tap_step             = lvdstsr ;          
assign tap_adj_mask         = lvdstamr;
assign train_threshold      = lvdsthr ; 
assign descram_en           = lvdsdser; 
assign always_on            = lvdstaor; 

endmodule

`undef  IDR      
`undef  VIDR     
`undef  DATER    
`undef  VERR     
`undef  TESTR    
`undef  ISR      
`undef  MISR     
`undef  SFRTR    
`undef  SFRR     
`undef  RAMPCTR  
`undef  RAMPIFSR 
`undef  DOSELR   
`undef  LVDSFTR  
`undef  LVDSTFR  
`undef  LVDSTSR  
`undef  LVDSTHR  
`undef  LVDSSR   
`undef  LVDSFSCR 
`undef  LVDSCECR 
`undef  LVDSTAMR 
`undef  LVDSDSER 
`undef  LVDSTAOR 
`undef  LVDSFSTR 
`undef  LVDSTSTR   
`undef  IMR      
`undef  MISR     
