OpenCores
URL https://opencores.org/ocsvn/dbg_interface/dbg_interface/trunk

Subversion Repositories dbg_interface

[/] [dbg_interface/] [trunk/] [rtl/] [verilog/] [dbg_wb.v] - Diff between revs 138 and 139

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 138 Rev 139
Line 1... Line 1...
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
////                                                              ////
////                                                              ////
////  dbg_wb.v                                                    ////
////  dbg_wb.v                                                    ////
////                                                              ////
////                                                              ////
////                                                              ////
////                                                              ////
////  This file is part of the SoC/OpenRISC Development Interface ////
////  This file is part of the SoC Debug Interface.               ////
////  http://www.opencores.org/projects/DebugInterface/           ////
////  http://www.opencores.org/projects/DebugInterface/           ////
////                                                              ////
////                                                              ////
////  Author(s):                                                  ////
////  Author(s):                                                  ////
////       Igor Mohor (igorm@opencores.org)                       ////
////       Igor Mohor (igorm@opencores.org)                       ////
////                                                              ////
////                                                              ////
Line 41... Line 41...
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//
//
// CVS Revision History
// CVS Revision History
//
//
// $Log: not supported by cvs2svn $
// $Log: not supported by cvs2svn $
 
// Revision 1.19  2004/03/22 16:35:46  igorm
 
// Temp version before changing dbg interface.
 
//
// Revision 1.18  2004/01/25 14:04:18  mohor
// Revision 1.18  2004/01/25 14:04:18  mohor
// All flipflops are reset.
// All flipflops are reset.
//
//
// Revision 1.17  2004/01/22 13:58:53  mohor
// Revision 1.17  2004/01/22 13:58:53  mohor
// Port signals are all set to zero after reset.
// Port signals are all set to zero after reset.
Line 163... Line 166...
input         wb_err_i;
input         wb_err_i;
output  [2:0] wb_cti_o;
output  [2:0] wb_cti_o;
output  [1:0] wb_bte_o;
output  [1:0] wb_bte_o;
 
 
reg           wb_cyc_o;
reg           wb_cyc_o;
reg    [31:0] wb_adr_o;
 
reg    [31:0] wb_dat_o;
 
reg     [3:0] wb_sel_o;
 
 
 
reg           tdo_o;
reg           tdo_o;
 
 
reg    [50:0] dr;
reg    [31:0] wb_dat_tmp, wb_dat_dsff;
 
reg    [31:0] wb_adr_dsff;
 
reg     [3:0] wb_sel_dsff;
 
reg           wb_we_dsff;
 
reg    [`DBG_WB_DR_LEN -1 :0] dr;
wire          enable;
wire          enable;
wire          cmd_cnt_en;
wire          cmd_cnt_en;
reg     [`DBG_WB_CMD_CNT_WIDTH -1:0] cmd_cnt;
reg     [`DBG_WB_CMD_CNT_WIDTH -1:0] cmd_cnt;
wire          cmd_cnt_end;
wire          cmd_cnt_end;
reg           cmd_cnt_end_q;
reg           cmd_cnt_end_q;
wire          addr_len_cnt_en;
reg           addr_len_cnt_en;
reg     [5:0] addr_len_cnt;
reg     [5:0] addr_len_cnt;
reg     [5:0] addr_len_cnt_limit;
 
wire          addr_len_cnt_end;
wire          addr_len_cnt_end;
wire          crc_cnt_en;
reg           addr_len_cnt_end_q;
reg     [5:0] crc_cnt;
reg           crc_cnt_en;
 
reg     [`DBG_WB_CRC_CNT_WIDTH -1:0] crc_cnt;
wire          crc_cnt_end;
wire          crc_cnt_end;
reg           crc_cnt_end_q;
reg           crc_cnt_end_q;
wire          data_cnt_en;
reg           data_cnt_en;
reg    [18:0] data_cnt;
reg    [`DBG_WB_DATA_CNT_WIDTH:0] data_cnt;
reg    [18:0] data_cnt_limit;
reg    [`DBG_WB_DATA_CNT_WIDTH:0] data_cnt_limit;
wire          data_cnt_end;
wire          data_cnt_end;
reg           data_cnt_end_q;
reg           data_cnt_end_q;
reg           status_reset_en;
 
 
 
reg           crc_match_reg;
reg           crc_match_reg;
 
 
reg     [2:0] cmd, cmd_old, dr_cmd_latched;
reg    [`DBG_WB_ACC_TYPE_LEN -1:0] acc_type;
reg    [31:0] adr;
reg    [`DBG_WB_ADR_LEN -1:0] adr;
reg    [15:0] len;
reg    [`DBG_WB_LEN_LEN -1:0] len;
 
reg    [`DBG_WB_LEN_LEN:0]    len_var;
reg           start_rd_tck;
reg           start_rd_tck;
reg           rd_tck_started;
reg           rd_tck_started;
reg           start_rd_sync1;
reg           start_rd_csff;
reg           start_wb_rd;
reg           start_wb_rd;
reg           start_wb_rd_q;
reg           start_wb_rd_q;
reg           start_wr_tck;
reg           start_wr_tck;
reg           start_wr_sync1;
reg           start_wr_csff;
reg           start_wb_wr;
reg           start_wb_wr;
reg           start_wb_wr_q;
reg           start_wb_wr_q;
 
 
wire          dr_read;
reg           status_cnt_en;
wire          dr_write;
 
wire          dr_go;
 
 
 
reg           dr_write_latched;
 
reg           dr_read_latched;
 
reg           dr_go_latched;
 
 
 
wire          status_cnt_end;
wire          status_cnt_end;
 
 
wire          byte, half, long;
wire          byte, half, long;
reg           byte_q, half_q, long_q;
reg           byte_q, half_q, long_q;
reg           byte_q2, half_q2, long_q2;
 
reg           cmd_read;
 
reg           cmd_write;
 
reg           cmd_go;
 
 
 
reg           status_cnt1, status_cnt2, status_cnt3, status_cnt4;
reg [`DBG_WB_STATUS_CNT_WIDTH -1:0] status_cnt;
 
 
reg [`DBG_WB_STATUS_LEN -1:0] status;
reg [`DBG_WB_STATUS_LEN -1:0] status;
 
 
reg           wb_error, wb_error_sync, wb_error_tck;
reg           wb_error, wb_error_csff, wb_error_tck;
reg           wb_overrun, wb_overrun_sync, wb_overrun_tck;
reg           wb_overrun, wb_overrun_csff, wb_overrun_tck;
reg           underrun_tck;
reg           underrun_tck;
 
 
reg           busy_wb;
reg           busy_wb;
reg           busy_tck;
reg           busy_tck;
reg           wb_end;
reg           wb_end;
reg           wb_end_rst;
reg           wb_end_rst;
reg           wb_end_rst_sync;
reg           wb_end_rst_csff;
reg           wb_end_sync;
reg           wb_end_csff;
reg           wb_end_tck, wb_end_tck_q;
reg           wb_end_tck, wb_end_tck_q;
reg           busy_sync;
reg           busy_csff;
reg           latch_data;
reg           latch_data;
 
reg           update_dr_csff, update_dr_wb;
 
 
reg           set_addr, set_addr_sync, set_addr_wb, set_addr_wb_q;
reg           set_addr, set_addr_csff, set_addr_wb, set_addr_wb_q;
reg           read_cycle;
 
reg           write_cycle;
 
reg     [2:0] rw_type;
 
wire   [31:0] input_data;
wire   [31:0] input_data;
 
 
wire          len_eq_0;
wire          len_eq_0;
wire          crc_cnt_31;
wire          crc_cnt_31;
 
 
reg     [1:0] ptr;
reg     [1:0] ptr;
reg     [2:0] fifo_cnt;
reg     [2:0] fifo_cnt;
wire          fifo_full;
wire          fifo_full;
wire          fifo_empty;
wire          fifo_empty;
reg     [7:0] mem [0:3];
reg     [7:0] mem [0:3];
reg     [2:0] mem_ptr;
reg     [2:0] mem_ptr_dsff;
reg           wishbone_ce_sync;
reg           wishbone_ce_csff;
reg           wishbone_ce_rst;
reg           mem_ptr_init;
wire          go_prelim;
reg [`DBG_WB_CMD_LEN -1: 0] curr_cmd;
 
wire          curr_cmd_go;
 
reg           curr_cmd_go_q;
 
wire          curr_cmd_wr_comm;
 
wire          curr_cmd_rd_comm;
 
wire          acc_type_read;
 
wire          acc_type_write;
 
wire          acc_type_8bit;
 
wire          acc_type_16bit;
 
wire          acc_type_32bit;
 
 
 
 
assign enable = wishbone_ce_i & shift_dr_i;
assign enable = wishbone_ce_i & shift_dr_i;
assign crc_en_o = enable & crc_cnt_end & (~status_cnt_end);
assign crc_en_o = enable & crc_cnt_end & (~status_cnt_end);
assign shift_crc_o = enable & status_cnt_end;  // Signals dbg module to shift out the CRC
assign shift_crc_o = enable & status_cnt_end;  // Signals dbg module to shift out the CRC
 
 
 
assign curr_cmd_go      = (curr_cmd == `DBG_WB_GO) && cmd_cnt_end;
 
assign curr_cmd_wr_comm = (curr_cmd == `DBG_WB_WR_COMM) && cmd_cnt_end;
 
assign curr_cmd_rd_comm = (curr_cmd == `DBG_WB_RD_COMM) && cmd_cnt_end;
 
 
 
assign acc_type_read    = (acc_type == `DBG_WB_READ8  || acc_type == `DBG_WB_READ16  || acc_type == `DBG_WB_READ32);
 
assign acc_type_write   = (acc_type == `DBG_WB_WRITE8 || acc_type == `DBG_WB_WRITE16 || acc_type == `DBG_WB_WRITE32);
 
 
 
assign acc_type_8bit    = (acc_type == `DBG_WB_READ8  || acc_type == `DBG_WB_WRITE8);
 
assign acc_type_16bit   = (acc_type == `DBG_WB_READ16 || acc_type == `DBG_WB_WRITE16);
 
assign acc_type_32bit   = (acc_type == `DBG_WB_READ32 || acc_type == `DBG_WB_WRITE32);
 
 
 
 
// Selecting where to take the data from 
// Selecting where to take the data from 
always @ (posedge tck_i or posedge rst_i)
always @ (posedge tck_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    ptr <= #1 2'h0;
    ptr <= #1 2'h0;
  else if (update_dr_i)
  else if (update_dr_i)
    ptr <= #1 2'h0;
    ptr <= #1 2'h0;
  else if (read_cycle & crc_cnt_31) // first latch
  else if (curr_cmd_go && acc_type_read && crc_cnt_31) // first latch
    ptr <= #1 ptr + 1'b1;
    ptr <= #1 ptr + 1'b1;
  else if (read_cycle & byte & (~byte_q))
  else if (curr_cmd_go && acc_type_read && byte && (!byte_q))
    ptr <= ptr + 1'd1;
    ptr <= ptr + 1'd1;
end
end
 
 
 
 
 
reg [799:0] dr_text;
// Shift register for shifting in and out the data
// Shift register for shifting in and out the data
always @ (posedge tck_i or posedge rst_i)
always @ (posedge tck_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    begin
    begin
      dr <= #1 51'h0;
 
      latch_data <= #1 1'b0;
      latch_data <= #1 1'b0;
 
      dr <= #1 {`DBG_WB_DR_LEN{1'b0}};
 
      dr_text = "reset";
 
    end
 
  else if (curr_cmd_rd_comm && crc_cnt_31)  // Latching data (from iternal regs)
 
    begin
 
      dr[`DBG_WB_ACC_TYPE_LEN + `DBG_WB_ADR_LEN + `DBG_WB_LEN_LEN -1:0] <= #1 {acc_type, adr, len};
 
      dr_text = "latch reg data";
    end
    end
  else if (read_cycle & crc_cnt_31)
  else if (acc_type_read && curr_cmd_go && crc_cnt_31)  // Latchind first data (from WB)
    begin
    begin
      dr[31:0] <= #1 input_data[31:0];
      dr[31:0] <= #1 input_data[31:0];
      latch_data <= #1 1'b1;
      latch_data <= #1 1'b1;
 
      dr_text = "latch first data";
    end
    end
  else if (read_cycle & crc_cnt_end)
  else if (acc_type_read && curr_cmd_go && crc_cnt_end) // Latching data (from WB)
    begin
    begin
      case (rw_type)  // synthesis parallel_case full_case
      case (acc_type)  // synthesis parallel_case full_case
        `WB_READ8 : begin
        `DBG_WB_READ8 : begin
                      if(byte & (~byte_q))
                      if(byte & (~byte_q))
                        begin
                        begin
                          case (ptr)    // synthesis parallel_case
                          case (ptr)    // synthesis parallel_case
                            2'b00 : dr[31:24] <= #1 input_data[31:24];
                            2'b00 : dr[31:24] <= #1 input_data[31:24];
                            2'b01 : dr[31:24] <= #1 input_data[23:16];
                            2'b01 : dr[31:24] <= #1 input_data[23:16];
                            2'b10 : dr[31:24] <= #1 input_data[15:8];
                            2'b10 : dr[31:24] <= #1 input_data[15:8];
                            2'b11 : dr[31:24] <= #1 input_data[7:0];
                            2'b11 : dr[31:24] <= #1 input_data[7:0];
                          endcase
                          endcase
                          latch_data <= #1 1'b1;
                          latch_data <= #1 1'b1;
 
                          dr_text = "latch_data byte";
                        end
                        end
                      else
                      else
                        begin
                        begin
                          dr[31:24] <= #1 {dr[30:24], 1'b0};
                          dr[31:24] <= #1 {dr[30:24], 1'b0};
                          latch_data <= #1 1'b0;
                          latch_data <= #1 1'b0;
 
                          dr_text = "shift byte";
                        end
                        end
                    end
                    end
        `WB_READ16: begin
        `DBG_WB_READ16: begin
                      if(half & (~half_q))
                      if(half & (~half_q))
                        begin
                        begin
                          if (ptr[1])
                          if (ptr[1])
                            dr[31:16] <= #1 input_data[15:0];
                            dr[31:16] <= #1 input_data[15:0];
                          else
                          else
                            dr[31:16] <= #1 input_data[31:16];
                            dr[31:16] <= #1 input_data[31:16];
                          latch_data <= #1 1'b1;
                          latch_data <= #1 1'b1;
 
                          dr_text = "latch_data_half";
                        end
                        end
                      else
                      else
                        begin
                        begin
                          dr[31:16] <= #1 {dr[30:16], 1'b0};
                          dr[31:16] <= #1 {dr[30:16], 1'b0};
                          latch_data <= #1 1'b0;
                          latch_data <= #1 1'b0;
 
                          dr_text = "shift half";
                        end
                        end
                    end
                    end
        `WB_READ32: begin
        `DBG_WB_READ32: begin
                      if(long & (~long_q))
                      if(long & (~long_q))
                        begin
                        begin
                          dr[31:0] <= #1 input_data[31:0];
                          dr[31:0] <= #1 input_data[31:0];
                          latch_data <= #1 1'b1;
                          latch_data <= #1 1'b1;
 
                          dr_text = "latch_data word";
                        end
                        end
                      else
                      else
                        begin
                        begin
                          dr[31:0] <= #1 {dr[30:0], 1'b0};
                          dr[31:0] <= #1 {dr[30:0], 1'b0};
                          latch_data <= #1 1'b0;
                          latch_data <= #1 1'b0;
 
                          dr_text = "shift word";
                        end
                        end
                    end
                    end
      endcase
      endcase
    end
    end
  else if (enable & ((~addr_len_cnt_end) | (~cmd_cnt_end) | ((~data_cnt_end) & write_cycle)))
  else if (enable && (!addr_len_cnt_end))
    begin
    begin
      dr <= #1 {dr[49:0], tdi_i};
      dr <= #1 {dr[`DBG_WB_DR_LEN -2:0], tdi_i};
      latch_data <= #1 1'b0;
      dr_text = "shift dr";
    end
    end
end
end
 
 
 
 
 
 
assign cmd_cnt_en = enable & (~cmd_cnt_end);
assign cmd_cnt_en = enable & (~cmd_cnt_end);
 
 
 
 
// Command counter
// Command counter
always @ (posedge tck_i or posedge rst_i)
always @ (posedge tck_i or posedge rst_i)
Line 365... Line 390...
  else if (cmd_cnt_en)
  else if (cmd_cnt_en)
    cmd_cnt <= #1 cmd_cnt + 1'b1;
    cmd_cnt <= #1 cmd_cnt + 1'b1;
end
end
 
 
 
 
assign addr_len_cnt_en = enable & cmd_cnt_end & (~addr_len_cnt_end);
// Assigning current command
 
 
 
 
// Address/length counter
 
always @ (posedge tck_i or posedge rst_i)
always @ (posedge tck_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    addr_len_cnt <= #1 6'h0;
    curr_cmd <= #1 {`DBG_WB_CMD_LEN{1'b0}};
  else if (update_dr_i)
  else if (update_dr_i)
    addr_len_cnt <= #1 6'h0;
    curr_cmd <= #1 {`DBG_WB_CMD_LEN{1'b0}};
  else if (addr_len_cnt_en)
  else if (cmd_cnt == (`DBG_WB_CMD_LEN -1))
    addr_len_cnt <= #1 addr_len_cnt + 1'b1;
    curr_cmd <= #1 {dr[`DBG_WB_CMD_LEN-2 :0], tdi_i};
end
end
 
 
 
 
assign data_cnt_en = enable & (~data_cnt_end) & (cmd_cnt_end & write_cycle | crc_cnt_end & read_cycle);
// Assigning current command
 
 
 
 
// Data counter
 
always @ (posedge tck_i or posedge rst_i)
always @ (posedge tck_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    data_cnt <= #1 19'h0;
    curr_cmd_go_q <= #1 1'b0;
  else if (update_dr_i)
  else
    data_cnt <= #1 19'h0;
    curr_cmd_go_q <= #1 curr_cmd_go;
  else if (data_cnt_en)
 
    data_cnt <= #1 data_cnt + 1'b1;
 
end
end
 
 
 
 
 
always @ (enable or cmd_cnt_end or addr_len_cnt_end or curr_cmd_wr_comm or curr_cmd_rd_comm or crc_cnt_end)
assign byte = data_cnt[2:0] == 3'd7;
 
assign half = data_cnt[3:0] == 4'd15;
 
assign long = data_cnt[4:0] == 5'd31;
 
 
 
 
 
always @ (posedge tck_i or posedge rst_i)
 
begin
begin
  if (rst_i)
  if (enable && (!addr_len_cnt_end))
    begin
    begin
      byte_q <= #1  1'b0;
      if (cmd_cnt_end && curr_cmd_wr_comm)
      half_q <= #1  1'b0;
        addr_len_cnt_en = 1'b1;
      long_q <= #1  1'b0;
      else if (crc_cnt_end && curr_cmd_rd_comm)
      byte_q2 <= #1 1'b0;
        addr_len_cnt_en = 1'b1;
      half_q2 <= #1 1'b0;
 
      long_q2 <= #1 1'b0;
 
    end
 
  else
  else
    begin
        addr_len_cnt_en = 1'b0;
      byte_q <= #1 byte;
 
      half_q <= #1 half;
 
      long_q <= #1 long;
 
      byte_q2 <= #1 byte_q;
 
      half_q2 <= #1 half_q;
 
      long_q2 <= #1 long_q;
 
    end
    end
 
  else
 
    addr_len_cnt_en = 1'b0;
end
end
 
 
 
 
assign dr_read = (dr[2:0] == `WB_READ8) || (dr[2:0] == `WB_READ16) || (dr[2:0] == `WB_READ32);
// Address/length counter
assign dr_write = (dr[2:0] == `WB_WRITE8) || (dr[2:0] == `WB_WRITE16) || (dr[2:0] == `WB_WRITE32);
 
assign dr_go = dr[2:0] == `WB_GO;
 
 
 
 
 
// Latching instruction
 
always @ (posedge tck_i or posedge rst_i)
always @ (posedge tck_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    begin
    addr_len_cnt <= #1 6'h0;
      dr_cmd_latched <= #1 3'h0;
 
      dr_read_latched  <= #1 1'b0;
 
      dr_write_latched  <= #1 1'b0;
 
      dr_go_latched  <= #1 1'b0;
 
    end
 
  else if (update_dr_i)
  else if (update_dr_i)
    begin
    addr_len_cnt <= #1 6'h0;
      dr_cmd_latched <= #1 3'h0;
  else if (addr_len_cnt_en)
      dr_read_latched  <= #1 1'b0;
    addr_len_cnt <= #1 addr_len_cnt + 1'b1;
      dr_write_latched  <= #1 1'b0;
 
      dr_go_latched  <= #1 1'b0;
 
    end
    end
  else if (cmd_cnt_end & (~cmd_cnt_end_q))
 
 
 
 
always @ (enable or data_cnt_end or cmd_cnt_end or curr_cmd_go or acc_type_write or acc_type_read or crc_cnt_end)
 
begin
 
  if (enable && (!data_cnt_end))
    begin
    begin
      dr_cmd_latched <= #1 dr[2:0];
      if (cmd_cnt_end && curr_cmd_go && acc_type_write)
      dr_read_latched <= #1 dr_read;
        data_cnt_en = 1'b1;
      dr_write_latched <= #1 dr_write;
      else if (crc_cnt_end && curr_cmd_go && acc_type_read)
      dr_go_latched <= #1 dr_go;
        data_cnt_en = 1'b1;
 
      else
 
        data_cnt_en = 1'b0;
    end
    end
 
  else
 
    data_cnt_en = 1'b0;
end
end
 
 
 
 
// Upper limit. Address/length counter counts until this value is reached
// Data counter
always @ (posedge tck_i or posedge rst_i)
always @ (posedge tck_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    addr_len_cnt_limit <= #1 6'd0;
    data_cnt <= #1 {`DBG_WB_DATA_CNT_WIDTH{1'b0}};
  else if (cmd_cnt == `DBG_WB_CMD_CNT_WIDTH'h2)
  else if (update_dr_i)
    begin
    data_cnt <= #1 {`DBG_WB_DATA_CNT_WIDTH{1'b0}};
      if ((~dr[0])  & (~tdi_i))                                   // (current command is WB_STATUS or WB_GO)
  else if (data_cnt_en)
        addr_len_cnt_limit <= #1 6'd0;
    data_cnt <= #1 data_cnt + 1'b1;
      else                                                        // (current command is WB_WRITEx or WB_READx)
 
        addr_len_cnt_limit <= #1 6'd48;
 
    end
 
end
end
 
 
 
 
assign go_prelim = (cmd_cnt == 2'h2) & dr[1] & (~dr[0]) & (~tdi_i);
 
 
 
 
 
// Upper limit. Data counter counts until this value is reached.
// Upper limit. Data counter counts until this value is reached.
always @ (posedge tck_i or posedge rst_i)
always @ (posedge tck_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    data_cnt_limit <= #1 19'h0;
    data_cnt_limit <= #1 {`DBG_WB_DATA_CNT_WIDTH{1'b0}};
  else if (update_dr_i)
  else if (update_dr_i)
    data_cnt_limit <= #1 {len, 3'b000};
    data_cnt_limit <= #1 {len + 1'b1, 3'b000};
end
end
 
 
 
 
assign crc_cnt_en = enable & (~crc_cnt_end) & (cmd_cnt_end & addr_len_cnt_end  & (~write_cycle) | (data_cnt_end & write_cycle));
always @ (enable or crc_cnt_end or curr_cmd_rd_comm or curr_cmd_wr_comm or curr_cmd_go or addr_len_cnt_end or data_cnt_end or acc_type_write or acc_type_read or cmd_cnt_end)
 
begin
 
  if (enable && (!crc_cnt_end) && cmd_cnt_end)
 
    begin
 
      if (addr_len_cnt_end && curr_cmd_wr_comm)
 
        crc_cnt_en = 1'b1;
 
      else if (data_cnt_end && curr_cmd_go && acc_type_write)
 
        crc_cnt_en = 1'b1;
 
      else if (cmd_cnt_end && (curr_cmd_go && acc_type_read || curr_cmd_rd_comm))
 
        crc_cnt_en = 1'b1;
 
      else
 
        crc_cnt_en = 1'b0;
 
    end
 
  else
 
    crc_cnt_en = 1'b0;
 
end
 
 
 
 
// crc counter
// crc counter
always @ (posedge tck_i or posedge rst_i)
always @ (posedge tck_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    crc_cnt <= #1 6'h0;
    crc_cnt <= #1 {`DBG_WB_CRC_CNT_WIDTH{1'b0}};
  else if(crc_cnt_en)
  else if(crc_cnt_en)
    crc_cnt <= #1 crc_cnt + 1'b1;
    crc_cnt <= #1 crc_cnt + 1'b1;
  else if (update_dr_i)
  else if (update_dr_i)
    crc_cnt <= #1 6'h0;
    crc_cnt <= #1 {`DBG_WB_CRC_CNT_WIDTH{1'b0}};
end
end
 
 
assign cmd_cnt_end  = cmd_cnt  == `DBG_WB_CMD_LEN;
assign cmd_cnt_end  = cmd_cnt  == `DBG_WB_CMD_LEN;
assign addr_len_cnt_end = addr_len_cnt == addr_len_cnt_limit;
assign addr_len_cnt_end = addr_len_cnt == `DBG_WB_DR_LEN;
assign crc_cnt_end  = crc_cnt  == 6'd32;
assign crc_cnt_end      = crc_cnt      == `DBG_WB_CRC_CNT_WIDTH'd32;
assign crc_cnt_31 = crc_cnt  == 6'd31;
assign crc_cnt_31       = crc_cnt      == `DBG_WB_CRC_CNT_WIDTH'd31;
assign data_cnt_end = (data_cnt == data_cnt_limit);
assign data_cnt_end = (data_cnt == data_cnt_limit);
 
 
always @ (posedge tck_i or posedge rst_i)
always @ (posedge tck_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    begin
    begin
      crc_cnt_end_q  <= #1 1'b0;
      crc_cnt_end_q  <= #1 1'b0;
      cmd_cnt_end_q  <= #1 1'b0;
      cmd_cnt_end_q  <= #1 1'b0;
      data_cnt_end_q <= #1 1'b0;
      data_cnt_end_q <= #1 1'b0;
 
      addr_len_cnt_end_q  <= #1 1'b0;
    end
    end
  else
  else
    begin
    begin
      crc_cnt_end_q  <= #1 crc_cnt_end;
      crc_cnt_end_q  <= #1 crc_cnt_end;
      cmd_cnt_end_q  <= #1 cmd_cnt_end;
      cmd_cnt_end_q  <= #1 cmd_cnt_end;
      data_cnt_end_q <= #1 data_cnt_end;
      data_cnt_end_q <= #1 data_cnt_end;
 
      addr_len_cnt_end_q  <= #1 addr_len_cnt_end;
    end
    end
end
end
 
 
 
 
// Status counter is made of 4 serialy connected registers
// Status counter is made of 4 serialy connected registers
always @ (posedge tck_i or posedge rst_i)
always @ (posedge tck_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    status_cnt1 <= #1 1'b0;
    status_cnt <= #1 {`DBG_WB_STATUS_CNT_WIDTH{1'b0}};
  else if (update_dr_i)
  else if (update_dr_i)
    status_cnt1 <= #1 1'b0;
    status_cnt <= #1 {`DBG_WB_STATUS_CNT_WIDTH{1'b0}};
  else if (data_cnt_end & read_cycle |
  else if (status_cnt_en)
           crc_cnt_end & (~read_cycle)
    status_cnt <= #1 status_cnt + 1'b1;
          )
 
    status_cnt1 <= #1 1'b1;
 
end
end
 
 
 
 
always @ (posedge tck_i or posedge rst_i)
always @ (enable or status_cnt_end or crc_cnt_end or curr_cmd_rd_comm or curr_cmd_wr_comm or curr_cmd_go or acc_type_write or data_cnt_end or addr_len_cnt_end)
begin
begin
  if (rst_i)
  if (enable && (!status_cnt_end))
    begin
    begin
      status_cnt2 <= #1 1'b0;
      if (crc_cnt_end && curr_cmd_wr_comm)
      status_cnt3 <= #1 1'b0;
        status_cnt_en = 1'b1;
      status_cnt4 <= #1 1'b0;
      else if (crc_cnt_end && curr_cmd_go && acc_type_write)
    end
        status_cnt_en = 1'b1;
  else if (update_dr_i)
      else if (data_cnt_end && curr_cmd_go && acc_type_read)
    begin
        status_cnt_en = 1'b1;
      status_cnt2 <= #1 1'b0;
      else if (addr_len_cnt_end && curr_cmd_rd_comm)
      status_cnt3 <= #1 1'b0;
        status_cnt_en = 1'b1;
      status_cnt4 <= #1 1'b0;
 
    end
 
  else
  else
    begin
        status_cnt_en = 1'b0;
      status_cnt2 <= #1 status_cnt1;
 
      status_cnt3 <= #1 status_cnt2;
 
      status_cnt4 <= #1 status_cnt3;
 
    end
    end
 
  else
 
    status_cnt_en = 1'b0;
end
end
 
 
 
 
assign status_cnt_end = status_cnt4;
assign status_cnt_end = status_cnt == `DBG_WB_STATUS_LEN;
 
 
 
 
// Status register
// Latching acc_type, address and length
always @ (posedge tck_i or posedge rst_i)
always @ (posedge tck_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    begin
    begin
    status <= #1 {`DBG_WB_STATUS_LEN{1'b0}};
      acc_type  <= #1 {`DBG_WB_ACC_TYPE_LEN{1'b0}};
    end
      adr       <= #1 {`DBG_WB_ADR_LEN{1'b0}};
  else if(crc_cnt_end & (~crc_cnt_end_q) & (~read_cycle))
      len       <= #1 {`DBG_WB_LEN_LEN{1'b0}};
    begin
      set_addr  <= #1 1'b0;
    status <= #1 {crc_match_i, wb_error_tck, wb_overrun_tck, busy_tck};
 
    end
 
  else if (data_cnt_end & (~data_cnt_end_q) & read_cycle)
 
    begin
 
    status <= #1 {crc_match_reg, wb_error_tck, underrun_tck, busy_tck};
 
    end
 
  else if (shift_dr_i & (~status_cnt_end))
 
    begin
 
    status <= #1 {status[0], status[`DBG_WB_STATUS_LEN -1:1]};
 
    end
 
end
 
// Following status is shifted out:
 
// 1. bit:          1 if crc is OK, else 0
 
// 2. bit:          1 while WB access is in progress (busy_tck), else 0
 
// 3. bit:          1 if overrun occured during write (data couldn't be written fast enough)
 
//                    or underrun occured during read (data couldn't be read fast enough)
 
// 4. bit:          1 if WB error occured, else 0
 
 
 
 
 
// TDO multiplexer
 
always @ (pause_dr_i or busy_tck or crc_cnt_end or crc_cnt_end_q or crc_match_i or
 
          data_cnt_end or data_cnt_end_q or read_cycle or crc_match_reg or status or dr)
 
begin
 
  if (pause_dr_i)
 
    begin
 
    tdo_o = busy_tck;
 
    end
 
  else if (crc_cnt_end & (~crc_cnt_end_q) & (~(read_cycle)))
 
    begin
 
      tdo_o = crc_match_i;
 
    end
 
  else if (read_cycle & crc_cnt_end & (~data_cnt_end))
 
    begin
 
    tdo_o = dr[31];
 
    end
    end
  else if (read_cycle & data_cnt_end & (~data_cnt_end_q))     // cmd is already updated
  else if(crc_cnt_end && (!crc_cnt_end_q) && crc_match_i && curr_cmd_wr_comm)
    begin
    begin
      tdo_o = crc_match_reg;
      acc_type  <= #1 dr[`DBG_WB_ACC_TYPE_LEN + `DBG_WB_ADR_LEN + `DBG_WB_LEN_LEN -1 : `DBG_WB_ADR_LEN + `DBG_WB_LEN_LEN];
 
      adr       <= #1 dr[`DBG_WB_ADR_LEN + `DBG_WB_LEN_LEN -1 : `DBG_WB_LEN_LEN];
 
      len       <= #1 dr[`DBG_WB_LEN_LEN -1:0];
 
      set_addr  <= #1 1'b1;
    end
    end
  else if (crc_cnt_end & data_cnt_end)  // cmd is already updated
  else if(wb_end_tck)               // Writing back the address
    begin
    begin
      tdo_o = status[0];
      adr  <= #1 wb_adr_dsff;
    end
    end
  else
  else
    begin
    set_addr <= #1 1'b0;
      tdo_o = 1'b0;
 
    end
 
end
end
 
 
 
 
 
 
always @ (posedge tck_i or posedge rst_i)
always @ (posedge tck_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    crc_match_reg <= #1 1'b0;
    crc_match_reg <= #1 1'b0;
  else if(crc_cnt_end & (~crc_cnt_end_q))
  else if(crc_cnt_end & (~crc_cnt_end_q))
    crc_match_reg <= #1 crc_match_i;
    crc_match_reg <= #1 crc_match_i;
end
end
 
 
 
 
// Latching instruction
 
always @ (posedge tck_i or posedge rst_i)
 
begin
 
  if (rst_i)
 
    begin
 
      cmd <= #1 3'h0;
 
      cmd_old <= #1 3'h0;
 
      cmd_read <= #1 1'b0;
 
      cmd_write <= #1 1'b0;
 
      cmd_go <= #1 1'b0;
 
    end
 
  else if(crc_cnt_end & (~crc_cnt_end_q) & crc_match_i)
 
    begin
 
      cmd <= #1 dr_cmd_latched;
 
      cmd_old <= #1 cmd;
 
      cmd_read <= #1 dr_read_latched;
 
      cmd_write <= #1 dr_write_latched;
 
      cmd_go <= #1 dr_go_latched;
 
    end
 
end
 
 
 
 
 
// Latching address
 
always @ (posedge tck_i or posedge rst_i)
 
begin
 
  if (rst_i)
 
    begin
 
      adr      <= #1 32'h0;
 
      set_addr <= #1 1'b0;
 
    end
 
  else if(crc_cnt_end & (~crc_cnt_end_q) & crc_match_i)
 
    begin
 
      if (dr_write_latched | dr_read_latched)
 
        begin
 
          adr <= #1 dr[47:16];
 
          set_addr <= #1 1'b1;
 
        end
 
    end
 
  else
 
    set_addr <= #1 1'b0;
 
end
 
 
 
 
 
// Length counter
// Length counter
always @ (posedge tck_i or posedge rst_i)
always @ (posedge tck_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    len <= #1 16'h0;
    len_var <= #1 {1'b0, {`DBG_WB_LEN_LEN{1'b0}}};
  else if(crc_cnt_end & (~crc_cnt_end_q) & crc_match_i & (dr_write_latched | dr_read_latched))
  else if(update_dr_i)
    len <= #1 dr[15:0];
    len_var <= #1 len + 1'b1;
  else if (start_rd_tck)
  else if (start_rd_tck)
    begin
    begin
      case (rw_type)  // synthesis parallel_case full_case
      case (acc_type)  // synthesis parallel_case full_case
        `WB_READ8 : len <= #1 len - 1'd1;
        `DBG_WB_READ8 :
        `WB_READ16: len <= #1 len - 2'd2;
                    if (len_var > 'd1)
        `WB_READ32: len <= #1 len - 3'd4;
                      len_var <= #1 len_var - 1'd1;
 
                    else
 
                      len_var <= #1 {1'b0, {`DBG_WB_LEN_LEN{1'b0}}};
 
        `DBG_WB_READ16:
 
                    if (len_var > 'd2)
 
                      len_var <= #1 len_var - 2'd2;
 
                    else
 
                      len_var <= #1 {1'b0, {`DBG_WB_LEN_LEN{1'b0}}};
 
        `DBG_WB_READ32:
 
                    if (len_var > 'd4)
 
                      len_var <= #1 len_var - 3'd4;
 
                    else
 
                      len_var <= #1 {1'b0, {`DBG_WB_LEN_LEN{1'b0}}};
      endcase
      endcase
    end
    end
end
end
 
 
 
 
assign len_eq_0 = len == 16'h0;
assign len_eq_0 = len_var == 'h0;
 
 
 
 
// Start wishbone read cycle
assign byte = data_cnt[2:0] == 3'd7;
always @ (posedge tck_i or posedge rst_i)
assign half = data_cnt[3:0] == 4'd15;
begin
assign long = data_cnt[4:0] == 5'd31;
  if (rst_i)
 
    start_rd_tck <= #1 1'b0;
 
  else if (read_cycle & (~dr_go_latched) & (~len_eq_0))              // First read after cmd is entered
 
    start_rd_tck <= #1 1'b1;
 
  else if ((~start_rd_tck) & read_cycle & (~len_eq_0) & (~fifo_full) & (~rd_tck_started))
 
    start_rd_tck <= #1 1'b1;
 
  else
 
    start_rd_tck <= #1 1'b0;
 
end
 
 
 
 
 
always @ (posedge tck_i or posedge rst_i)
always @ (posedge tck_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    rd_tck_started <= #1 1'b0;
 
  else if (update_dr_i)
 
    rd_tck_started <= #1 1'b0;
 
  else if (start_rd_tck)
 
    rd_tck_started <= #1 1'b1;
 
  else if (wb_end_tck & (~wb_end_tck_q))
 
    rd_tck_started <= #1 1'b0;
 
end
 
 
 
 
 
always @ (posedge tck_i or posedge rst_i)
 
begin
begin
  if (rst_i)
      byte_q <= #1  1'b0;
    read_cycle <= #1 1'b0;
      half_q <= #1  1'b0;
  else if (update_dr_i)
      long_q <= #1  1'b0;
    read_cycle <= #1 1'b0;
 
  else if (cmd_read & go_prelim)
 
    read_cycle <= #1 1'b1;
 
end
end
 
  else
 
 
always @ (posedge tck_i or posedge rst_i)
 
begin
begin
  if (rst_i)
      byte_q <= #1 byte;
    rw_type <= #1 3'h0;
      half_q <= #1 half;
  else if ((cmd_read | cmd_write) & go_prelim)
      long_q <= #1 long;
    rw_type <= #1 cmd;
 
end
end
 
 
 
 
always @ (posedge tck_i or posedge rst_i)
 
begin
 
  if (rst_i)
 
    write_cycle <= #1 1'b0;
 
  else if (update_dr_i)
 
    write_cycle <= #1 1'b0;
 
  else if (cmd_write & go_prelim)
 
    write_cycle <= #1 1'b1;
 
end
end
 
 
 
 
// Start wishbone write cycle
// Start wishbone write cycle
always @ (posedge tck_i or posedge rst_i)
always @ (posedge tck_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    begin
    begin
      start_wr_tck <= #1 1'b0;
      start_wr_tck <= #1 1'b0;
      wb_dat_o <= #1 32'h0;
      wb_dat_tmp <= #1 32'h0;
    end
    end
  else if (write_cycle)
  else if (curr_cmd_go && acc_type_write)
    begin
    begin
      case (rw_type)  // synthesis parallel_case full_case
      case (acc_type)  // synthesis parallel_case full_case
        `WB_WRITE8  : begin
        `DBG_WB_WRITE8  : begin
                        if (byte_q & (~byte_q2))
                        if (byte_q)
                          begin
                          begin
                            start_wr_tck <= #1 1'b1;
                            start_wr_tck <= #1 1'b1;
                            wb_dat_o <= #1 {4{dr[7:0]}};
                            wb_dat_tmp <= #1 {4{dr[7:0]}};
                          end
                          end
                        else
                        else
                          begin
                          begin
                            start_wr_tck <= #1 1'b0;
                            start_wr_tck <= #1 1'b0;
                          end
                          end
                      end
                      end
        `WB_WRITE16 : begin
        `DBG_WB_WRITE16 : begin
                        if (half_q & (~half_q2))
                        if (half_q)
                          begin
                          begin
                            start_wr_tck <= #1 1'b1;
                            start_wr_tck <= #1 1'b1;
                            wb_dat_o <= #1 {2{dr[15:0]}};
                            wb_dat_tmp <= #1 {2{dr[15:0]}};
                          end
                          end
                        else
                        else
                          begin
                          begin
                            start_wr_tck <= #1 1'b0;
                            start_wr_tck <= #1 1'b0;
                          end
                          end
                      end
                      end
        `WB_WRITE32 : begin
        `DBG_WB_WRITE32 : begin
                        if (long_q & (~long_q2))
                        if (long_q)
                          begin
                          begin
                            start_wr_tck <= #1 1'b1;
                            start_wr_tck <= #1 1'b1;
                            wb_dat_o <= #1 dr[31:0];
                            wb_dat_tmp <= #1 dr[31:0];
                          end
                          end
                        else
                        else
                          begin
                          begin
                            start_wr_tck <= #1 1'b0;
                            start_wr_tck <= #1 1'b0;
                          end
                          end
Line 803... Line 709...
  else
  else
    start_wr_tck <= #1 1'b0;
    start_wr_tck <= #1 1'b0;
end
end
 
 
 
 
 
// wb_dat_o in WB clk domain
 
always @ (posedge wb_clk_i)
 
begin
 
  wb_dat_dsff <= #1 wb_dat_tmp;
 
end
 
 
 
assign wb_dat_o = wb_dat_dsff;
 
 
 
 
 
// Start wishbone read cycle
 
always @ (posedge tck_i or posedge rst_i)
 
begin
 
  if (rst_i)
 
    start_rd_tck <= #1 1'b0;
 
  else if (curr_cmd_go && (!curr_cmd_go_q) && acc_type_read)              // First read after cmd is entered
 
    start_rd_tck <= #1 1'b1;
 
  else if ((!start_rd_tck) && curr_cmd_go && acc_type_read  && (!len_eq_0) && (!fifo_full) && (!rd_tck_started))
 
    start_rd_tck <= #1 1'b1;
 
  else
 
    start_rd_tck <= #1 1'b0;
 
end
 
 
 
 
 
always @ (posedge tck_i or posedge rst_i)
 
begin
 
  if (rst_i)
 
    rd_tck_started <= #1 1'b0;
 
  else if (update_dr_i || wb_end_tck && (!wb_end_tck_q))
 
    rd_tck_started <= #1 1'b0;
 
  else if (start_rd_tck)
 
    rd_tck_started <= #1 1'b1;
 
end
 
 
 
 
 
 
always @ (posedge wb_clk_i or posedge rst_i)
always @ (posedge wb_clk_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    begin
    begin
      start_rd_sync1  <= #1 1'b0;
      start_rd_csff   <= #1 1'b0;
      start_wb_rd     <= #1 1'b0;
      start_wb_rd     <= #1 1'b0;
      start_wb_rd_q   <= #1 1'b0;
      start_wb_rd_q   <= #1 1'b0;
 
 
      start_wr_sync1  <= #1 1'b0;
      start_wr_csff   <= #1 1'b0;
      start_wb_wr     <= #1 1'b0;
      start_wb_wr     <= #1 1'b0;
      start_wb_wr_q   <= #1 1'b0;
      start_wb_wr_q   <= #1 1'b0;
 
 
      set_addr_sync   <= #1 1'b0;
      set_addr_csff   <= #1 1'b0;
      set_addr_wb     <= #1 1'b0;
      set_addr_wb     <= #1 1'b0;
      set_addr_wb_q   <= #1 1'b0;
      set_addr_wb_q   <= #1 1'b0;
    end
    end
  else
  else
    begin
    begin
      start_rd_sync1  <= #1 start_rd_tck;
      start_rd_csff   <= #1 start_rd_tck;
      start_wb_rd     <= #1 start_rd_sync1;
      start_wb_rd     <= #1 start_rd_csff;
      start_wb_rd_q   <= #1 start_wb_rd;
      start_wb_rd_q   <= #1 start_wb_rd;
 
 
      start_wr_sync1  <= #1 start_wr_tck;
      start_wr_csff   <= #1 start_wr_tck;
      start_wb_wr     <= #1 start_wr_sync1;
      start_wb_wr     <= #1 start_wr_csff;
      start_wb_wr_q   <= #1 start_wb_wr;
      start_wb_wr_q   <= #1 start_wb_wr;
 
 
      set_addr_sync   <= #1 set_addr;
      set_addr_csff   <= #1 set_addr;
      set_addr_wb     <= #1 set_addr_sync;
      set_addr_wb     <= #1 set_addr_csff;
      set_addr_wb_q   <= #1 set_addr_wb;
      set_addr_wb_q   <= #1 set_addr_wb;
    end
    end
end
end
 
 
 
 
// wb_cyc_o
// wb_cyc_o
always @ (posedge wb_clk_i or posedge rst_i)
always @ (posedge wb_clk_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    wb_cyc_o <= #1 1'b0;
    wb_cyc_o <= #1 1'b0;
  else if ((start_wb_wr & (~start_wb_wr_q)) | (start_wb_rd & (~start_wb_rd_q)))
  else if ((start_wb_wr && (!start_wb_wr_q)) || (start_wb_rd && (!start_wb_rd_q)))
    wb_cyc_o <= #1 1'b1;
    wb_cyc_o <= #1 1'b1;
  else if (wb_ack_i | wb_err_i)
  else if (wb_ack_i || wb_err_i)
    wb_cyc_o <= #1 1'b0;
    wb_cyc_o <= #1 1'b0;
end
end
 
 
 
 
// wb_adr_o logic
// wb_adr_o logic
always @ (posedge wb_clk_i or posedge rst_i)
always @ (posedge wb_clk_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    wb_adr_o <= #1 32'h0;
    wb_adr_dsff <= #1 32'h0;
  else if (set_addr_wb & (~set_addr_wb_q)) // Setting starting address
  else if (set_addr_wb && (!set_addr_wb_q)) // Setting starting address
    wb_adr_o <= #1 adr;
    wb_adr_dsff <= #1 adr;
  else if (wb_ack_i)
  else if (wb_ack_i)
    begin
    begin
      if ((rw_type == `WB_WRITE8) | (rw_type == `WB_READ8))
      if ((acc_type == `DBG_WB_WRITE8) || (acc_type == `DBG_WB_READ8))
        wb_adr_o <= #1 wb_adr_o + 1'd1;
        wb_adr_dsff <= #1 wb_adr_dsff + 1'd1;
      else if ((rw_type == `WB_WRITE16) | (rw_type == `WB_READ16))
      else if ((acc_type == `DBG_WB_WRITE16) || (acc_type == `DBG_WB_READ16))
        wb_adr_o <= #1 wb_adr_o + 2'd2;
        wb_adr_dsff <= #1 wb_adr_dsff + 2'd2;
      else
      else
        wb_adr_o <= #1 wb_adr_o + 3'd4;
        wb_adr_dsff <= #1 wb_adr_dsff + 3'd4;
    end
    end
end
end
 
 
 
 
 
assign wb_adr_o = wb_adr_dsff;
 
 
 
 
//    adr   byte  |  short  |  long
//    adr   byte  |  short  |  long
//     0    1000     1100      1111
//     0    1000     1100      1111
//     1    0100     err       err
//     1    0100     err       err
//     2    0010     0011      err
//     2    0010     0011      err
//     3    0001     err       err
//     3    0001     err       err
// wb_sel_o logic
// wb_sel_o logic
 
 
always @ (posedge wb_clk_i or posedge rst_i)
always @ (posedge wb_clk_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    wb_sel_o[3:0] <= #1 4'h0;
    wb_sel_dsff[3:0] <= #1 4'h0;
  else
  else
    begin
    begin
      wb_sel_o[0] <= #1 (rw_type[1:0] == 2'b11) & (wb_adr_o[1:0] == 2'b00) | (rw_type[1:0] == 2'b01) & (wb_adr_o[1:0] == 2'b11) |
      case ({wb_adr_dsff[1:0], acc_type_8bit, acc_type_16bit, acc_type_32bit}) // synthesis parallel_case full_case
                        (rw_type[1:0] == 2'b10) & (wb_adr_o[1:0] == 2'b10);
        {2'd0, 3'b100} : wb_sel_dsff[3:0] <= #1 4'h8;
      wb_sel_o[1] <= #1 (rw_type[1:0] == 2'b11) & (wb_adr_o[1:0] == 2'b00) | (rw_type[1] ^ rw_type[0]) & (wb_adr_o[1:0] == 2'b10);
        {2'd0, 3'b010} : wb_sel_dsff[3:0] <= #1 4'hC;
      wb_sel_o[2] <= #1 (rw_type[1]) & (wb_adr_o[1:0] == 2'b00) | (rw_type[1:0] == 2'b01) & (wb_adr_o[1:0] == 2'b01);
        {2'd0, 3'b001} : wb_sel_dsff[3:0] <= #1 4'hF;
      wb_sel_o[3] <= #1 (wb_adr_o[1:0] == 2'b00);
        {2'd1, 3'b100} : wb_sel_dsff[3:0] <= #1 4'h4;
 
        {2'd2, 3'b100} : wb_sel_dsff[3:0] <= #1 4'h2;
 
        {2'd2, 3'b010} : wb_sel_dsff[3:0] <= #1 4'h3;
 
        {2'd3, 3'b100} : wb_sel_dsff[3:0] <= #1 4'h1;
 
      endcase
    end
    end
end
end
 
 
 
 
assign wb_we_o = write_cycle;
assign wb_sel_o = wb_sel_dsff;
 
 
 
 
 
always @ (posedge wb_clk_i)
 
begin
 
  wb_we_dsff <= #1 curr_cmd_go && acc_type_write;
 
end
 
 
 
 
 
assign wb_we_o = wb_we_dsff;
assign wb_cab_o = 1'b0;
assign wb_cab_o = 1'b0;
assign wb_stb_o = wb_cyc_o;
assign wb_stb_o = wb_cyc_o;
assign wb_cti_o = 3'h0;     // always performing single access
assign wb_cti_o = 3'h0;     // always performing single access
assign wb_bte_o = 2'h0;     // always performing single access
assign wb_bte_o = 2'h0;     // always performing single access
 
 
 
 
 
 
// Logic for detecting end of transaction
// Logic for detecting end of transaction
always @ (posedge wb_clk_i or posedge rst_i)
always @ (posedge wb_clk_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    wb_end <= #1 1'b0;
    wb_end <= #1 1'b0;
  else if (wb_ack_i | wb_err_i)
  else if (wb_ack_i || wb_err_i)
    wb_end <= #1 1'b1;
    wb_end <= #1 1'b1;
  else if (wb_end_rst)
  else if (wb_end_rst)
    wb_end <= #1 1'b0;
    wb_end <= #1 1'b0;
end
end
 
 
 
 
always @ (posedge tck_i or posedge rst_i)
always @ (posedge tck_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    begin
    begin
      wb_end_sync <= #1 1'b0;
      wb_end_csff  <= #1 1'b0;
      wb_end_tck  <= #1 1'b0;
      wb_end_tck  <= #1 1'b0;
      wb_end_tck_q<= #1 1'b0;
      wb_end_tck_q<= #1 1'b0;
    end
    end
  else
  else
    begin
    begin
      wb_end_sync <= #1 wb_end;
      wb_end_csff  <= #1 wb_end;
      wb_end_tck  <= #1 wb_end_sync;
      wb_end_tck   <= #1 wb_end_csff;
      wb_end_tck_q<= #1 wb_end_tck;
      wb_end_tck_q<= #1 wb_end_tck;
    end
    end
end
end
 
 
 
 
always @ (posedge wb_clk_i or posedge rst_i)
always @ (posedge wb_clk_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
 
    begin
 
      wb_end_rst_csff <= #1 1'b0;
 
      wb_end_rst      <= #1 1'b0;
 
    end
 
  else
 
    begin
 
      wb_end_rst_csff <= #1 wb_end_tck;
 
      wb_end_rst      <= #1 wb_end_rst_csff;
 
    end
 
end
 
 
 
 
 
always @ (posedge wb_clk_i or posedge rst_i)
 
begin
 
  if (rst_i)
    busy_wb <= #1 1'b0;
    busy_wb <= #1 1'b0;
  else if (wb_end_rst)
  else if (wb_end_rst)
    busy_wb <= #1 1'b0;
    busy_wb <= #1 1'b0;
  else if (wb_cyc_o)
  else if (wb_cyc_o)
    busy_wb <= #1 1'b1;
    busy_wb <= #1 1'b1;
Line 940... Line 913...
 
 
always @ (posedge tck_i or posedge rst_i)
always @ (posedge tck_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    begin
    begin
      busy_sync <= #1 1'b0;
      busy_csff       <= #1 1'b0;
      busy_tck <= #1 1'b0;
      busy_tck <= #1 1'b0;
    end
 
  else
 
    begin
 
      busy_sync <= #1 busy_wb;
 
      busy_tck <= #1 busy_sync;
 
    end
 
end
 
 
 
 
      update_dr_csff  <= #1 1'b0;
always @ (posedge wb_clk_i or posedge rst_i)
      update_dr_wb    <= #1 1'b0;
begin
 
  if (rst_i)
 
    begin
 
      wb_end_rst_sync <= #1 1'b0;
 
      wb_end_rst      <= #1 1'b0;
 
    end
    end
  else
  else
    begin
    begin
      wb_end_rst_sync <= #1 wb_end_tck;
      busy_csff       <= #1 busy_wb;
      wb_end_rst  <= #1 wb_end_rst_sync;
      busy_tck        <= #1 busy_csff;
 
 
 
      update_dr_csff  <= #1 update_dr_i;
 
      update_dr_wb    <= #1 update_dr_csff;
    end
    end
end
end
 
 
 
 
// Detecting WB error
// Detecting WB error
Line 973... Line 937...
begin
begin
  if (rst_i)
  if (rst_i)
    wb_error <= #1 1'b0;
    wb_error <= #1 1'b0;
  else if(wb_err_i)
  else if(wb_err_i)
    wb_error <= #1 1'b1;
    wb_error <= #1 1'b1;
  else if(wb_ack_i & status_reset_en) // error remains active until STATUS read is performed
  else if(update_dr_wb) // error remains active until update_dr arrives
    wb_error <= #1 1'b0;
    wb_error <= #1 1'b0;
end
end
 
 
 
 
always @ (posedge tck_i or posedge rst_i)
 
begin
 
  if (rst_i)
 
    begin
 
      wb_error_sync <= #1 1'b0;
 
      wb_error_tck  <= #1 1'b0;
 
    end
 
  else
 
    begin
 
      wb_error_sync <= #1 wb_error;
 
      wb_error_tck  <= #1 wb_error_sync;
 
    end
 
end
 
 
 
 
 
// Detecting overrun when write operation.
// Detecting overrun when write operation.
always @ (posedge wb_clk_i or posedge rst_i)
always @ (posedge wb_clk_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    wb_overrun <= #1 1'b0;
    wb_overrun <= #1 1'b0;
  else if(start_wb_wr & (~start_wb_wr_q) & wb_cyc_o)
  else if(start_wb_wr && (!start_wb_wr_q) && wb_cyc_o)
    wb_overrun <= #1 1'b1;
    wb_overrun <= #1 1'b1;
  else if((wb_ack_i | wb_err_i) & status_reset_en) // error remains active until STATUS read is performed
  else if(update_dr_wb) // error remains active until update_dr arrives
    wb_overrun <= #1 1'b0;
    wb_overrun <= #1 1'b0;
end
end
 
 
always @ (posedge tck_i or posedge rst_i)
 
begin
 
  if (rst_i)
 
    begin
 
      wb_overrun_sync <= #1 1'b0;
 
      wb_overrun_tck  <= #1 1'b0;
 
    end
 
  else
 
    begin
 
      wb_overrun_sync <= #1 wb_overrun;
 
      wb_overrun_tck  <= #1 wb_overrun_sync;
 
    end
 
end
 
 
 
 
 
// Detecting underrun when read operation
// Detecting underrun when read operation
always @ (posedge tck_i or posedge rst_i)
always @ (posedge tck_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    underrun_tck <= #1 1'b0;
    underrun_tck <= #1 1'b0;
  else if(latch_data & fifo_empty & (~data_cnt_end))
  else if(latch_data && fifo_empty && (!data_cnt_end))
    underrun_tck <= #1 1'b1;
    underrun_tck <= #1 1'b1;
  else if(read_cycle & status_reset_en) // error remains active until STATUS read is performed
  else if(update_dr_i) // error remains active until update_dr arrives
    underrun_tck <= #1 1'b0;
    underrun_tck <= #1 1'b0;
end
end
 
 
 
 
 
 
// wb_error is locked until WB_STATUS is performed
 
always @ (posedge tck_i or posedge rst_i)
always @ (posedge tck_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    status_reset_en <= 1'b0;
    begin
  else if((cmd_old == `WB_STATUS) & (cmd !== `WB_STATUS))
      wb_error_csff   <= #1 1'b0;
    status_reset_en <= #1 1'b1;
      wb_error_tck    <= #1 1'b0;
 
 
 
      wb_overrun_csff <= #1 1'b0;
 
      wb_overrun_tck  <= #1 1'b0;
 
    end
  else
  else
    status_reset_en <= #1 1'b0;
    begin
 
      wb_error_csff   <= #1 wb_error;
 
      wb_error_tck    <= #1 wb_error_csff;
 
 
 
      wb_overrun_csff <= #1 wb_overrun;
 
      wb_overrun_tck  <= #1 wb_overrun_csff;
 
    end
end
end
 
 
 
 
 
 
always @ (posedge wb_clk_i or posedge rst_i)
always @ (posedge wb_clk_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    begin
    begin
      wishbone_ce_sync <= #1 1'b0;
      wishbone_ce_csff  <= #1 1'b0;
      wishbone_ce_rst  <= #1 1'b0;
      mem_ptr_init      <= #1 1'b0;
    end
    end
  else
  else
    begin
    begin
      wishbone_ce_sync <= #1  wishbone_ce_i;
      wishbone_ce_csff  <= #1  wishbone_ce_i;
      wishbone_ce_rst  <= #1 ~wishbone_ce_sync;
      mem_ptr_init      <= #1 ~wishbone_ce_csff;
    end
    end
end
end
 
 
 
 
// Logic for latching data that is read from wishbone
// Logic for latching data that is read from wishbone
always @ (posedge wb_clk_i or posedge rst_i)
always @ (posedge wb_clk_i or posedge rst_i)
begin
begin
  if (rst_i)
  if (rst_i)
    mem_ptr <= #1 3'h0;
    mem_ptr_dsff <= #1 3'h0;
  else if(wishbone_ce_rst)
  else if(mem_ptr_init)
    mem_ptr <= #1 3'h0;
    mem_ptr_dsff <= #1 3'h0;
  else if (wb_ack_i)
  else if (wb_ack_i)
    begin
    begin
      if (rw_type == `WB_READ8)
      if (acc_type == `DBG_WB_READ8)
        mem_ptr <= #1 mem_ptr + 1'd1;
        mem_ptr_dsff <= #1 mem_ptr_dsff + 1'd1;
      else if (rw_type == `WB_READ16)
      else if (acc_type == `DBG_WB_READ16)
        mem_ptr <= #1 mem_ptr + 2'd2;
        mem_ptr_dsff <= #1 mem_ptr_dsff + 2'd2;
    end
    end
end
end
 
 
 
 
// Logic for latching data that is read from wishbone
// Logic for latching data that is read from wishbone
always @ (posedge wb_clk_i)
always @ (posedge wb_clk_i)
begin
begin
  if (wb_ack_i)
  if (wb_ack_i)
    begin
    begin
      case (wb_sel_o)    // synthesis parallel_case full_case 
      case (wb_sel_dsff)    // synthesis parallel_case full_case
        4'b1000  :  mem[mem_ptr[1:0]] <= #1 wb_dat_i[31:24];            // byte 
        4'b1000  :  mem[mem_ptr_dsff[1:0]] <= #1 wb_dat_i[31:24];            // byte
        4'b0100  :  mem[mem_ptr[1:0]] <= #1 wb_dat_i[23:16];            // byte
        4'b0100  :  mem[mem_ptr_dsff[1:0]] <= #1 wb_dat_i[23:16];            // byte
        4'b0010  :  mem[mem_ptr[1:0]] <= #1 wb_dat_i[15:08];            // byte
        4'b0010  :  mem[mem_ptr_dsff[1:0]] <= #1 wb_dat_i[15:08];            // byte
        4'b0001  :  mem[mem_ptr[1:0]] <= #1 wb_dat_i[07:00];            // byte
        4'b0001  :  mem[mem_ptr_dsff[1:0]] <= #1 wb_dat_i[07:00];            // byte
 
 
        4'b1100  :                                                      // half
        4'b1100  :                                                      // half
                    begin
                    begin
                      mem[mem_ptr[1:0]]      <= #1 wb_dat_i[31:24];
                      mem[mem_ptr_dsff[1:0]]      <= #1 wb_dat_i[31:24];
                      mem[mem_ptr[1:0]+1'b1] <= #1 wb_dat_i[23:16];
                      mem[mem_ptr_dsff[1:0]+1'b1] <= #1 wb_dat_i[23:16];
                    end
                    end
        4'b0011  :                                                      // half
        4'b0011  :                                                      // half
                    begin
                    begin
                      mem[mem_ptr[1:0]]      <= #1 wb_dat_i[15:08];
                      mem[mem_ptr_dsff[1:0]]      <= #1 wb_dat_i[15:08];
                      mem[mem_ptr[1:0]+1'b1] <= #1 wb_dat_i[07:00];
                      mem[mem_ptr_dsff[1:0]+1'b1] <= #1 wb_dat_i[07:00];
                    end
                    end
        4'b1111  :                                                      // long
        4'b1111  :                                                      // long
                    begin
                    begin
                      mem[0] <= #1 wb_dat_i[31:24];
                      mem[0] <= #1 wb_dat_i[31:24];
                      mem[1] <= #1 wb_dat_i[23:16];
                      mem[1] <= #1 wb_dat_i[23:16];
Line 1119... Line 1063...
begin
begin
  if (rst_i)
  if (rst_i)
    fifo_cnt <= #1 3'h0;
    fifo_cnt <= #1 3'h0;
  else if (update_dr_i)
  else if (update_dr_i)
    fifo_cnt <= #1 3'h0;
    fifo_cnt <= #1 3'h0;
  else if (wb_end_tck & (~wb_end_tck_q) & (~latch_data))  // incrementing
  else if (wb_end_tck && (!wb_end_tck_q) && (!latch_data) && (!fifo_full))  // incrementing
    begin
    begin
      case (rw_type)  // synthesis parallel_case full_case
      case (acc_type)  // synthesis parallel_case full_case
        `WB_READ8 : fifo_cnt <= #1 fifo_cnt + 1'd1;
        `DBG_WB_READ8 : fifo_cnt <= #1 fifo_cnt + 1'd1;
        `WB_READ16: fifo_cnt <= #1 fifo_cnt + 2'd2;
        `DBG_WB_READ16: fifo_cnt <= #1 fifo_cnt + 2'd2;
        `WB_READ32: fifo_cnt <= #1 fifo_cnt + 3'd4;
        `DBG_WB_READ32: fifo_cnt <= #1 fifo_cnt + 3'd4;
      endcase
      endcase
    end
    end
  else if (~(wb_end_tck & (~wb_end_tck_q)) & latch_data)  // decrementing
  else if (!(wb_end_tck && (!wb_end_tck_q)) && latch_data && (!fifo_empty))  // decrementing
    begin
    begin
      case (rw_type)  // synthesis parallel_case full_case
      case (acc_type)  // synthesis parallel_case full_case
        `WB_READ8 : fifo_cnt <= #1 fifo_cnt - 1'd1;
        `DBG_WB_READ8 : fifo_cnt <= #1 fifo_cnt - 1'd1;
        `WB_READ16: fifo_cnt <= #1 fifo_cnt - 2'd2;
        `DBG_WB_READ16: fifo_cnt <= #1 fifo_cnt - 2'd2;
        `WB_READ32: fifo_cnt <= #1 fifo_cnt - 3'd4;
        `DBG_WB_READ32: fifo_cnt <= #1 fifo_cnt - 3'd4;
      endcase
      endcase
    end
    end
end
end
 
 
 
 
assign fifo_full = fifo_cnt == 3'h4;
assign fifo_full = fifo_cnt == 3'h4;
assign fifo_empty = fifo_cnt == 3'h0;
assign fifo_empty = fifo_cnt == 3'h0;
 
 
 
reg [799:0] tdo_text;
 
 
 
// TDO multiplexer
 
always @ (pause_dr_i or busy_tck or crc_cnt_end or crc_cnt_end_q or curr_cmd_wr_comm or curr_cmd_go or acc_type_write or acc_type_read or crc_match_i or data_cnt_end or dr or data_cnt_end_q or crc_match_reg or status_cnt_en or status or addr_len_cnt_end or addr_len_cnt_end_q)
 
begin
 
  if (pause_dr_i)
 
    begin
 
    tdo_o = busy_tck;
 
    tdo_text = "busy_tck";
 
    end
 
  else if (crc_cnt_end && (!crc_cnt_end_q) && (curr_cmd_wr_comm || curr_cmd_go && acc_type_write ))
 
    begin
 
      tdo_o = ~crc_match_i;
 
      tdo_text = "crc_match_i";
 
    end
 
  else if (curr_cmd_go && acc_type_read && crc_cnt_end && (!data_cnt_end))
 
    begin
 
      tdo_o = dr[31];
 
      tdo_text = "dr[31]";
 
    end
 
  else if (curr_cmd_go && acc_type_read && data_cnt_end && (!data_cnt_end_q))
 
    begin
 
      tdo_o = ~crc_match_reg;
 
      tdo_text = "crc_match_reg";
 
    end
 
  else if (curr_cmd_rd_comm && addr_len_cnt_end && (!addr_len_cnt_end_q))
 
    begin
 
      tdo_o = ~crc_match_reg;
 
      tdo_text = "crc_match_reg_rd_comm";
 
    end
 
  else if (curr_cmd_rd_comm && crc_cnt_end && (!addr_len_cnt_end))
 
    begin
 
      tdo_o = dr[`DBG_WB_ACC_TYPE_LEN + `DBG_WB_ADR_LEN + `DBG_WB_LEN_LEN -1];
 
      tdo_text = "rd_comm data";
 
    end
 
  else if (status_cnt_en)
 
    begin
 
      tdo_o = status[3];
 
      tdo_text = "status";
 
    end
 
  else
 
    begin
 
      tdo_o = 1'b0;
 
      tdo_text = "zero";
 
    end
 
end
 
 
 
reg [799:0] status_text;
 
// Status register
 
always @ (posedge tck_i or posedge rst_i)
 
begin
 
  if (rst_i)
 
    begin
 
    status <= #1 {`DBG_WB_STATUS_LEN{1'b0}};
 
    status_text = "reset";
 
    end
 
  else if(crc_cnt_end && (!crc_cnt_end_q) && (!(curr_cmd_go && acc_type_read)))
 
    begin
 
    status <= #1 {1'b0, wb_error_tck, wb_overrun_tck, crc_match_i};
 
    status_text = "latch ni read";
 
    end
 
  else if (data_cnt_end && (!data_cnt_end_q) && curr_cmd_go && acc_type_read)
 
    begin
 
    status <= #1 {1'b0, wb_error_tck, underrun_tck, crc_match_reg};
 
    status_text = "latch read";
 
    end
 
  else if (addr_len_cnt_end && (!addr_len_cnt_end) && curr_cmd_rd_comm)
 
    begin
 
    status <= #1 {1'b0, 1'b0, 1'b0, crc_match_reg};
 
    status_text = "rd_comm";
 
    end
 
  else if (shift_dr_i && (!status_cnt_end))
 
    begin
 
    status <= #1 {status[`DBG_WB_STATUS_LEN -2:0], status[`DBG_WB_STATUS_LEN -1]};
 
    status_text = "shifting";
 
    end
 
end
 
// Following status is shifted out (MSB first):
 
// 3. bit:          1 if crc is OK, else 0
 
// 2. bit:          1'b0
 
// 1. bit:          1 if WB error occured, else 0
 
// 0. bit:          1 if overrun occured during write (data couldn't be written fast enough)
 
//                    or underrun occured during read (data couldn't be read fast enough)
 
 
 
 
endmodule
endmodule
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.