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

Subversion Repositories sdcard_mass_storage_controller

[/] [sdcard_mass_storage_controller/] [trunk/] [bench/] [sdc_dma/] [verilog/] [wb_slave_behavioral.v] - Diff between revs 79 and 81

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

Rev 79 Rev 81
Line 1... Line 1...
 
//////////////////////////////////////////////////////////////////////
 
////                                                              ////
 
////  File name: wb_slave_behavioral.v                            ////
 
////                                                              ////
 
////  This file is part of the Ethernet IP core project           ////
 
////  http://www.opencores.org/projects/ethmac/                   ////
 
////                                                              ////
 
////  Author(s):                                                  ////
 
////      - Tadej Markovic, tadej@opencores.org                   ////
 
////                                                              ////
 
////  All additional information is available in the README.txt   ////
 
////  file.                                                       ////
 
////                                                              ////
 
////                                                              ////
 
//////////////////////////////////////////////////////////////////////
 
////                                                              ////
 
//// Copyright (C) 2002 Tadej Markovic, tadej@opencores.org       ////
 
////                                                              ////
 
//// This source file may be used and distributed without         ////
 
//// restriction provided that this copyright statement is not    ////
 
//// removed from the file and that any derivative work contains  ////
 
//// the original copyright notice and the associated disclaimer. ////
 
////                                                              ////
 
//// This source file is free software; you can redistribute it   ////
 
//// and/or modify it under the terms of the GNU Lesser General   ////
 
//// Public License as published by the Free Software Foundation; ////
 
//// either version 2.1 of the License, or (at your option) any   ////
 
//// later version.                                               ////
 
////                                                              ////
 
//// This source is distributed in the hope that it will be       ////
 
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
 
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
 
//// PURPOSE.  See the GNU Lesser General Public License for more ////
 
//// details.                                                     ////
 
////                                                              ////
 
//// You should have received a copy of the GNU Lesser General    ////
 
//// Public License along with this source; if not, download it   ////
 
//// from http://www.opencores.org/lgpl.shtml                     ////
 
////                                                              ////
 
//////////////////////////////////////////////////////////////////////
 
//
 
// CVS Revision History
 
//
 
// $Log: not supported by cvs2svn $
 
// Revision 1.2  2002/09/13 12:29:14  mohor
 
// Headers changed.
 
//
 
// Revision 1.1  2002/09/13 11:57:21  mohor
 
// New testbench. Thanks to Tadej M - "The Spammer".
 
//
 
// Revision 1.2  2002/03/06 09:10:56  mihad
 
// Added missing include statements
 
//
 
// Revision 1.1  2002/02/01 13:39:43  mihad
 
// Initial testbench import. Still under development
 
//
 
//
 
 
 
`include "timescale.v"
 
`include "wb_model_defines.v"
 
module WB_SLAVE_BEHAVIORAL
 
(
 
        CLK_I,
 
        RST_I,
 
        ACK_O,
 
        ADR_I,
 
        CYC_I,
 
        DAT_O,
 
        DAT_I,
 
        ERR_O,
 
        RTY_O,
 
        SEL_I,
 
        STB_I,
 
        WE_I,
 
        CAB_I
 
);
 
 
 
/*------------------------------------------------------------------------------------------------------
 
WISHBONE signals
 
------------------------------------------------------------------------------------------------------*/
 
input                   CLK_I;
 
input                   RST_I;
 
output                  ACK_O;
 
input   `WB_ADDR_TYPE   ADR_I;
 
input                   CYC_I;
 
output  `WB_DATA_TYPE   DAT_O;
 
input   `WB_DATA_TYPE   DAT_I;
 
output                  ERR_O;
 
output                  RTY_O;
 
input   `WB_SEL_TYPE    SEL_I;
 
input                   STB_I;
 
input                   WE_I;
 
input                   CAB_I;
 
 
 
reg     `WB_DATA_TYPE   DAT_O;
 
 
 
/*------------------------------------------------------------------------------------------------------
 
Asynchronous dual-port RAM signals for storing and fetching the data
 
------------------------------------------------------------------------------------------------------*/
 
//reg     `WB_DATA_TYPE wb_memory [0:16777215]; // WB memory - 24 addresses connected - 2 LSB not used
 
reg     `WB_DATA_TYPE wb_memory [0:1048575]; // WB memory - 20 addresses connected - 2 LSB not used
 
reg     `WB_DATA_TYPE mem_wr_data_out;
 
reg     `WB_DATA_TYPE mem_rd_data_in;
 
 
 
/*------------------------------------------------------------------------------------------------------
 
Maximum values for WAIT and RETRY counters and which response !!!
 
------------------------------------------------------------------------------------------------------*/
 
reg     [2:0]  a_e_r_resp; // tells with which cycle_termination_signal must wb_slave respond !
 
reg     [3:0]  wait_cyc;
 
reg     [7:0]  max_retry;
 
 
 
// assign registers to default state while in reset
 
always@(RST_I)
 
begin
 
  if (RST_I)
 
  begin
 
    a_e_r_resp <= 3'b000; // do not respond
 
    wait_cyc   <= 4'b0; // no wait cycles
 
    max_retry  <= 8'h0; // no retries
 
  end
 
end //reset
 
 
 
task cycle_response;
 
  input [2:0]  ack_err_rty_resp; // acknowledge, error or retry response input flags
 
  input [3:0]  wait_cycles; // if wait cycles before each data termination cycle (ack, err or rty)
 
  input [7:0]  retry_cycles; // noumber of retry cycles before acknowledge cycle
 
begin
 
  // assign values
 
  a_e_r_resp <= #1 ack_err_rty_resp;
 
  wait_cyc   <= #1 wait_cycles;
 
  max_retry  <= #1 retry_cycles;
 
end
 
endtask // cycle_response
 
 
 
/*------------------------------------------------------------------------------------------------------
 
Tasks for writing and reading to and from memory !!!
 
------------------------------------------------------------------------------------------------------*/
 
reg    `WB_ADDR_TYPE task_wr_adr_i;
 
reg    `WB_ADDR_TYPE task_rd_adr_i;
 
reg    `WB_DATA_TYPE task_dat_i;
 
reg    `WB_DATA_TYPE task_dat_o;
 
reg    `WB_SEL_TYPE  task_sel_i;
 
reg                  task_wr_data;
 
reg                  task_data_written;
 
reg    `WB_DATA_TYPE task_mem_wr_data;
 
 
 
// write to memory
 
task wr_mem;
 
  input  `WB_ADDR_TYPE adr_i;
 
  input  `WB_DATA_TYPE dat_i;
 
  input  `WB_SEL_TYPE  sel_i;
 
begin
 
  task_data_written = 0;
 
  task_wr_adr_i = adr_i;
 
  task_dat_i = dat_i;
 
  task_sel_i = sel_i;
 
  task_wr_data = 1;
 
  wait(task_data_written);
 
  task_wr_data = 0;
 
end
 
endtask
 
 
 
// read from memory
 
task rd_mem;
 
  input  `WB_ADDR_TYPE adr_i;
 
  output `WB_DATA_TYPE dat_o;
 
  input  `WB_SEL_TYPE  sel_i;
 
begin
 
  task_rd_adr_i = adr_i;
 
  task_sel_i = sel_i;
 
  #1;
 
  dat_o = task_dat_o;
 
end
 
endtask
 
 
 
/*------------------------------------------------------------------------------------------------------
 
Internal signals and logic
 
------------------------------------------------------------------------------------------------------*/
 
reg            calc_ack;
 
reg            calc_err;
 
reg            calc_rty;
 
 
 
reg     [7:0]  retry_cnt;
 
reg     [7:0]  retry_num;
 
reg            retry_expired;
 
 
 
// Retry counter
 
always@(posedge RST_I or posedge CLK_I)
 
begin
 
  if (RST_I)
 
    retry_cnt <= #1 8'h00;
 
  else
 
  begin
 
    if (calc_ack || calc_err)
 
      retry_cnt <= #1 8'h00;
 
    else if (calc_rty)
 
      retry_cnt <= #1 retry_num;
 
  end
 
end
 
 
 
always@(retry_cnt or max_retry)
 
begin
 
  if (retry_cnt < max_retry)
 
  begin
 
    retry_num = retry_cnt + 1'b1;
 
    retry_expired = 1'b0;
 
  end
 
  else
 
  begin
 
    retry_num = retry_cnt;
 
    retry_expired = 1'b1;
 
  end
 
end
 
 
 
reg     [3:0]  wait_cnt;
 
reg     [3:0]  wait_num;
 
reg            wait_expired;
 
 
 
// Wait counter
 
always@(posedge RST_I or posedge CLK_I)
 
begin
 
  if (RST_I)
 
    wait_cnt <= #1 4'h0;
 
  else
 
  begin
 
    if (wait_expired || ~STB_I)
 
      wait_cnt <= #1 4'h0;
 
    else
 
      wait_cnt <= #1 wait_num;
 
  end
 
end
 
 
 
always@(wait_cnt or wait_cyc or STB_I or a_e_r_resp or retry_expired)
 
begin
 
  if ((wait_cyc > 0) && (STB_I))
 
  begin
 
    if (wait_cnt < wait_cyc) // 4'h2)
 
    begin
 
      wait_num = wait_cnt + 1'b1;
 
      wait_expired = 1'b0;
 
      calc_ack = 1'b0;
 
      calc_err = 1'b0;
 
      calc_rty = 1'b0;
 
    end
 
    else
 
    begin
 
      wait_num = wait_cnt;
 
      wait_expired = 1'b1;
 
      if (a_e_r_resp == 3'b100)
 
      begin
 
        calc_ack = 1'b1;
 
        calc_err = 1'b0;
 
        calc_rty = 1'b0;
 
      end
 
      else
 
      if (a_e_r_resp == 3'b010)
 
      begin
 
        calc_ack = 1'b0;
 
        calc_err = 1'b1;
 
        calc_rty = 1'b0;
 
      end
 
      else
 
      if (a_e_r_resp == 3'b001)
 
      begin
 
        calc_err = 1'b0;
 
        if (retry_expired)
 
        begin
 
          calc_ack = 1'b1;
 
          calc_rty = 1'b0;
 
        end
 
        else
 
        begin
 
          calc_ack = 1'b0;
 
          calc_rty = 1'b1;
 
        end
 
      end
 
      else
 
      begin
 
        calc_ack = 1'b0;
 
        calc_err = 1'b0;
 
        calc_rty = 1'b0;
 
      end
 
    end
 
  end
 
  else
 
  if ((wait_cyc == 0) && (STB_I))
 
  begin
 
    wait_num = 2'h0;
 
    wait_expired = 1'b1;
 
    if (a_e_r_resp == 3'b100)
 
    begin
 
      calc_ack = 1'b1;
 
      calc_err = 1'b0;
 
      calc_rty = 1'b0;
 
    end
 
    else if (a_e_r_resp == 3'b010)
 
    begin
 
      calc_ack = 1'b0;
 
      calc_err = 1'b1;
 
      calc_rty = 1'b0;
 
    end
 
    else if (a_e_r_resp == 3'b001)
 
    begin
 
      calc_err = 1'b0;
 
      if (retry_expired)
 
      begin
 
        calc_ack = 1'b1;
 
        calc_rty = 1'b0;
 
      end
 
      else
 
      begin
 
        calc_ack = 1'b0;
 
        calc_rty = 1'b1;
 
      end
 
    end
 
    else
 
    begin
 
      calc_ack = 1'b0;
 
      calc_err = 1'b0;
 
      calc_rty = 1'b0;
 
    end
 
  end
 
  else
 
  begin
 
    wait_num = 2'h0;
 
    wait_expired = 1'b0;
 
    calc_ack = 1'b0;
 
    calc_err = 1'b0;
 
    calc_rty = 1'b0;
 
  end
 
end
 
 
 
wire rd_sel = (CYC_I && STB_I && ~WE_I);
 
wire wr_sel = (CYC_I && STB_I && WE_I);
 
 
 
// Generate cycle termination signals
 
assign ACK_O = calc_ack && STB_I;
 
assign ERR_O = calc_err && STB_I;
 
assign RTY_O = calc_rty && STB_I;
 
 
 
// Assign address to asynchronous memory
 
always@(RST_I or ADR_I)
 
begin
 
  if (RST_I) // this is added because at start of test bench we need address change in order to get data!
 
  begin
 
    #1 mem_rd_data_in = `WB_DATA_WIDTH'hxxxx_xxxx;
 
  end
 
  else
 
  begin
 
//    #1 mem_rd_data_in = wb_memory[ADR_I[25:2]];
 
    #1 mem_rd_data_in = wb_memory[ADR_I[21:2]];
 
  end
 
end
 
 
 
// Data input/output interface
 
always@(rd_sel or mem_rd_data_in or RST_I)
 
begin
 
  if (RST_I)
 
    DAT_O <=#1 `WB_DATA_WIDTH'hxxxx_xxxx;       // assign outputs to unknown state while in reset
 
  else if (rd_sel)
 
    DAT_O <=#1 mem_rd_data_in;
 
  else
 
    DAT_O <=#1 `WB_DATA_WIDTH'hxxxx_xxxx;
 
end
 
 
 
 
 
always@(RST_I or task_rd_adr_i)
 
begin
 
  if (RST_I)
 
    task_dat_o = `WB_DATA_WIDTH'hxxxx_xxxx;
 
  else
 
    task_dat_o = wb_memory[task_rd_adr_i[21:2]];
 
end
 
always@(CLK_I or wr_sel or task_wr_data or ADR_I or task_wr_adr_i or
 
        mem_wr_data_out or DAT_I or task_mem_wr_data or task_dat_i or
 
        SEL_I or task_sel_i)
 
begin
 
  if (task_wr_data)
 
  begin
 
    task_mem_wr_data = wb_memory[task_wr_adr_i[21:2]];
 
 
 
    if (task_sel_i[3])
 
      task_mem_wr_data[31:24] = task_dat_i[31:24];
 
    if (task_sel_i[2])
 
      task_mem_wr_data[23:16] = task_dat_i[23:16];
 
    if (task_sel_i[1])
 
      task_mem_wr_data[15: 8] = task_dat_i[15: 8];
 
    if (task_sel_i[0])
 
      task_mem_wr_data[ 7: 0] = task_dat_i[ 7: 0];
 
 
 
    wb_memory[task_wr_adr_i[21:2]] = task_mem_wr_data; // write data
 
    task_data_written = 1;
 
  end
 
  else if (wr_sel && ~CLK_I)
 
  begin
 
//    mem_wr_data_out = wb_memory[ADR_I[25:2]]; // if no SEL_I is active, old value will be written
 
    mem_wr_data_out = wb_memory[ADR_I[21:2]]; // if no SEL_I is active, old value will be written
 
 
 
    if (SEL_I[3])
 
      mem_wr_data_out[31:24] = DAT_I[31:24];
 
    if (SEL_I[2])
 
      mem_wr_data_out[23:16] = DAT_I[23:16];
 
    if (SEL_I[1])
 
      mem_wr_data_out[15: 8] = DAT_I[15: 8];
 
    if (SEL_I[0])
 
      mem_wr_data_out[ 7: 0] = DAT_I[ 7: 0];
 
 
 
//    wb_memory[ADR_I[25:2]]  <= mem_wr_data_out; // write data
 
    wb_memory[ADR_I[21:2]]  = mem_wr_data_out; // write data
 
  end
 
end
 
 
 
endmodule
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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