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

Subversion Repositories pci

[/] [pci/] [tags/] [rel_7/] [bench/] [verilog/] [wb_slave_behavioral.v] - Diff between revs 34 and 63

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

Rev 34 Rev 63
Line 40... Line 40...
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//
//
// CVS Revision History
// CVS Revision History
//
//
// $Log: not supported by cvs2svn $
// $Log: not supported by cvs2svn $
 
// Revision 1.2  2002/03/06 09:10:56  mihad
 
// Added missing include statements
 
//
// Revision 1.1  2002/02/01 13:39:43  mihad
// Revision 1.1  2002/02/01 13:39:43  mihad
// Initial testbench import. Still under development
// Initial testbench import. Still under development
//
//
//
//
 
 
`include "pci_testbench_defines.v"
`include "pci_testbench_defines.v"
`include "timescale.v"
`include "timescale.v"
`include "pci_constants.v"
`include "pci_constants.v"
 
 
module WB_SLAVE_BEHAVIORAL
module WB_SLAVE_BEHAVIORAL
(
(
        CLK_I,
        CLK_I,
        RST_I,
        RST_I,
        ACK_O,
        ACK_O,
Line 65... Line 69...
        STB_I,
        STB_I,
        WE_I,
        WE_I,
        CAB_I
        CAB_I
);
);
 
 
/*----------------------------------------------------------------------------------------------------------------------
/*------------------------------------------------------------------------------------------------------
WISHBONE signals
WISHBONE signals
----------------------------------------------------------------------------------------------------------------------*/
------------------------------------------------------------------------------------------------------*/
input                                   CLK_I ;
input                                   CLK_I ;
input                                   RST_I ;
input                                   RST_I ;
output                                  ACK_O ;
output                                  ACK_O ;
input   `WB_ADDR_TYPE   ADR_I ;
input   `WB_ADDR_TYPE   ADR_I ;
input                                   CYC_I ;
input                                   CYC_I ;
Line 82... Line 86...
input   `WB_SEL_TYPE    SEL_I ;
input   `WB_SEL_TYPE    SEL_I ;
input                                   STB_I ;
input                                   STB_I ;
input                                   WE_I ;
input                                   WE_I ;
input                                   CAB_I ;
input                                   CAB_I ;
 
 
//reg                           ACK_O ;
reg     `WB_DATA_TYPE   DAT_O;
//reg                           ERR_O ;
 
//reg                           RTY_O ;
 
reg             [31:0]   DAT_O ;
 
 
 
/*----------------------------------------------------------------------------------------------------------------------
/*------------------------------------------------------------------------------------------------------
Asynchronous dual-port RAM signals for storing and fetching the data
Asynchronous dual-port RAM signals for storing and fetching the data
----------------------------------------------------------------------------------------------------------------------*/
------------------------------------------------------------------------------------------------------*/
reg     [31:0]   wb_memory [0:1023] ; // data for WB memory - 16 LSB addresses are connected
//reg     `WB_DATA_TYPE wb_memory [0:16777215]; // WB memory - 24 addresses connected - 2 LSB not used
reg             [31:0]   mem_wr_data_out ;
reg     `WB_DATA_TYPE wb_memory [0:1048575]; // WB memory - 20 addresses connected - 2 LSB not used
reg             [31:0]   mem_rd_data_in ;
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 !!!
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             [2:0]    a_e_r_resp ;            // tells with which cycle_termination_signal must wb_slave respond !
reg                             wait_cyc ;
reg     [3:0]  wait_cyc;
reg             [7:0]    max_retry ;
reg             [7:0]    max_retry ;
 
 
// assign registers to default state while in reset
// assign registers to default state while in reset
always@(RST_I)
always@(RST_I)
begin
begin
    if (RST_I)
    if (RST_I)
    begin
    begin
        a_e_r_resp      <= 3'b000 ; // do not respond
        a_e_r_resp      <= 3'b000 ; // do not respond
        wait_cyc        <= 1'b0 ;       // no wait cycles
    wait_cyc   <= 4'b0; // no wait cycles
        max_retry       <= 8'h0 ;       // no retries
        max_retry       <= 8'h0 ;       // no retries
    end
    end
end //reset
end //reset
 
 
task cycle_response ;
task cycle_response ;
        input [2:0]              ack_err_rty_resp ;      // acknowledge, error or retry response input flags
        input [2:0]              ack_err_rty_resp ;      // acknowledge, error or retry response input flags
        input                   wait_cycles ;           // if wait cycles before each data termination cycle (ack, err or rty)
  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
        input [7:0]              retry_cycles ;          // noumber of retry cycles before acknowledge cycle
begin
begin
    // assign values
    // assign values
    a_e_r_resp  <= #1 ack_err_rty_resp ;
    a_e_r_resp  <= #1 ack_err_rty_resp ;
        wait_cyc        <= #1 wait_cycles ;
        wait_cyc        <= #1 wait_cycles ;
    max_retry   <= #1 retry_cycles ;
    max_retry   <= #1 retry_cycles ;
end
end
endtask // cycle_response
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;
 
    integer current_byte ;
 
    integer current_bit ;
 
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;
 
    */
 
 
 
    task_mem_wr_data = wb_memory[adr_i[21:2]];
 
 
 
    for (current_byte = 0 ; current_byte < `WB_DATA_WIDTH / 8 ; current_byte = current_byte + 1'b1)
 
    begin
 
        // check sel_i for every byte
 
        if (sel_i[current_byte])
 
        begin
 
            // have to write a bit at a time, because dynamic range bouds are not allowed
 
            for (current_bit = 0 ; current_bit < 8 ; current_bit = current_bit + 1'b1)
 
                task_mem_wr_data[current_byte * 8 + current_bit] = dat_i[current_byte * 8 + current_bit] ;
 
        end
 
    end
 
    /*if (sel_i[3])
 
      task_mem_wr_data[31:24] = dat_i[31:24];
 
    if (sel_i[2])
 
      task_mem_wr_data[23:16] = dat_i[23:16];
 
    if (sel_i[1])
 
      task_mem_wr_data[15: 8] = dat_i[15: 8];
 
    if (sel_i[0])
 
      task_mem_wr_data[ 7: 0] = dat_i[ 7: 0];
 
    */
 
    wb_memory[adr_i[21:2]] = task_mem_wr_data; // write data
 
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
Internal signals and logic
----------------------------------------------------------------------------------------------------------------------*/
------------------------------------------------------------------------------------------------------*/
reg                             calc_ack ;
reg                             calc_ack ;
reg                             calc_err ;
reg                             calc_err ;
reg                             calc_rty ;
reg                             calc_rty ;
 
 
reg             [7:0]    retry_cnt ;
reg             [7:0]    retry_cnt ;
reg             [7:0]    retry_num ;
reg             [7:0]    retry_num ;
reg                             retry_expired ;
reg                             retry_expired ;
reg                             retry_rst ;
 
 
 
// RESET retry counter
// Retry counter
always@(posedge RST_I or posedge CLK_I)
always@(posedge RST_I or posedge CLK_I)
begin
begin
        if (RST_I)
        if (RST_I)
                retry_rst <= 1'b1 ;
    retry_cnt <= #1 8'h00;
        else
        else
                retry_rst <= calc_ack || calc_err ;
 
end
 
 
 
// Retry counter
 
always@(posedge retry_rst or negedge calc_rty)
 
begin
begin
        if (retry_rst)
    if (calc_ack || calc_err)
                retry_cnt <= #`FF_DELAY 8'h00 ;
      retry_cnt <= #1 8'h00;
        else
    else if (calc_rty)
                retry_cnt <= #`FF_DELAY retry_num ;
      retry_cnt <= #1 retry_num;
end
end
 
end
 
 
always@(retry_cnt or max_retry)
always@(retry_cnt or max_retry)
begin
begin
        if (retry_cnt < max_retry)
        if (retry_cnt < max_retry)
        begin
        begin
                retry_num = retry_cnt + 1'b1 ;
                retry_num = retry_cnt + 1'b1 ;
                retry_expired = #10 1'b0 ;
    retry_expired = 1'b0;
        end
        end
        else
        else
        begin
        begin
                retry_num = retry_cnt ;
                retry_num = retry_cnt ;
                retry_expired = #10 1'b1 ;
    retry_expired = 1'b1;
        end
        end
end
end
 
 
reg             [1:0]    wait_cnt ;
reg     [3:0]  wait_cnt;
reg             [1:0]    wait_num ;
reg     [3:0]  wait_num;
reg                             wait_expired ;
reg                             wait_expired ;
reg                             reset_wait ;
 
 
 
 
// Wait counter
always@(posedge RST_I or posedge CLK_I)
always@(posedge RST_I or posedge CLK_I)
begin
begin
        if (RST_I)
        if (RST_I)
                reset_wait <= #`FF_DELAY 1'b1 ;
    wait_cnt <= #1 4'h0;
        else
        else
                reset_wait <= #`FF_DELAY (wait_expired || ~STB_I) ;
 
end
 
 
 
// Wait counter
 
always@(posedge reset_wait or posedge CLK_I)
 
begin
begin
        if (reset_wait)
    if (wait_expired || ~STB_I)
                wait_cnt <= #`FF_DELAY 4'h0 ;
      wait_cnt <= #1 4'h0;
        else
        else
                wait_cnt <= #`FF_DELAY wait_num ;
      wait_cnt <= #1 wait_num;
 
  end
end
end
 
 
always@(wait_cnt or wait_cyc or STB_I or a_e_r_resp or retry_expired)
always@(wait_cnt or wait_cyc or STB_I or a_e_r_resp or retry_expired)
begin
begin
        if ((wait_cyc) && (STB_I))
  if ((wait_cyc > 0) && (STB_I))
        begin
        begin
                if (wait_cnt < 2'h2)
    if (wait_cnt < wait_cyc) // 4'h2)
                begin
                begin
                        wait_num = wait_cnt + 1'b1 ;
                        wait_num = wait_cnt + 1'b1 ;
                        wait_expired = 1'b0 ;
                        wait_expired = 1'b0 ;
                        calc_ack = 1'b0 ;
                        calc_ack = 1'b0 ;
                        calc_err = 1'b0 ;
                        calc_err = 1'b0 ;
Line 241... Line 304...
                                calc_rty = 1'b0 ;
                                calc_rty = 1'b0 ;
                        end
                        end
                end
                end
        end
        end
        else
        else
        if ((~wait_cyc) && (STB_I))
  if ((wait_cyc == 0) && (STB_I))
        begin
        begin
                wait_num = 2'h0 ;
                wait_num = 2'h0 ;
                wait_expired = 1'b1 ;
                wait_expired = 1'b1 ;
                if (a_e_r_resp == 3'b100)
                if (a_e_r_resp == 3'b100)
                begin
                begin
                        calc_ack = 1'b1 ;
                        calc_ack = 1'b1 ;
                        calc_err = 1'b0 ;
                        calc_err = 1'b0 ;
                        calc_rty = 1'b0 ;
                        calc_rty = 1'b0 ;
                end
                end
                else
    else if (a_e_r_resp == 3'b010)
                if (a_e_r_resp == 3'b010)
 
                begin
                begin
                        calc_ack = 1'b0 ;
                        calc_ack = 1'b0 ;
                        calc_err = 1'b1 ;
                        calc_err = 1'b1 ;
                        calc_rty = 1'b0 ;
                        calc_rty = 1'b0 ;
                end
                end
                else
    else if (a_e_r_resp == 3'b001)
                if (a_e_r_resp == 3'b001)
 
                begin
                begin
                        calc_err = 1'b0 ;
                        calc_err = 1'b0 ;
                        if (retry_expired)
                        if (retry_expired)
                        begin
                        begin
                                calc_ack = 1'b1 ;
                                calc_ack = 1'b1 ;
Line 294... Line 355...
 
 
wire    rd_sel = (CYC_I && STB_I && ~WE_I) ;
wire    rd_sel = (CYC_I && STB_I && ~WE_I) ;
wire    wr_sel = (CYC_I && STB_I && WE_I) ;
wire    wr_sel = (CYC_I && STB_I && WE_I) ;
 
 
// Generate cycle termination signals
// Generate cycle termination signals
assign  ACK_O = calc_ack && STB_I ;
assign ACK_O = calc_ack && STB_I && CYC_I;
assign  ERR_O = calc_err && STB_I ;
assign ERR_O = calc_err && STB_I && CYC_I;
assign  RTY_O = calc_rty && STB_I ;
assign RTY_O = calc_rty && STB_I && CYC_I;
 
 
// Assign address to asynchronous memory
// Assign address to asynchronous memory
always@(ADR_I or RST_I)
always@(RST_I or ADR_I)
begin
begin
        if (RST_I) // this is added because at start of test bench we need address change in order to get data!
        if (RST_I) // this is added because at start of test bench we need address change in order to get data!
                mem_rd_data_in = 32'hxxxx_xxxx ;
  begin
 
    #1 mem_rd_data_in = `WB_DATA_WIDTH'hxxxx_xxxx;
 
  end
        else
        else
                mem_rd_data_in = wb_memory[ADR_I[11:2]] ;
  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
end
 
 
// assign outputs to unknown state while in reset
/*// Data input/output interface
always@(RST_I)
always@(rd_sel or mem_rd_data_in or RST_I)
begin
begin
    if (RST_I)
  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
 
    ACK_O or
 
    WE_I  or
 
    ADR_I
 
)
    begin
    begin
                DAT_O <= 32'hxxxx_xxxx ;
    if ((ACK_O === 1'b1) && (RST_I === 1'b0) && (WE_I === 1'b0))
 
        DAT_O <= #1 wb_memory[ADR_I[21:2]] ;
 
    else
 
        DAT_O <= #1 {`WB_DATA_WIDTH{1'bx}} ;
    end
    end
end //reset
 
 
 
// Data input/output interface
always@(RST_I or task_rd_adr_i)
always@(rd_sel or wr_sel or mem_rd_data_in or DAT_I or SEL_I or mem_wr_data_out)
 
begin
begin
        if (rd_sel)
  if (RST_I)
        begin
    task_dat_o = `WB_DATA_WIDTH'hxxxx_xxxx;
                DAT_O = mem_rd_data_in ;
  else
        end
    task_dat_o = wb_memory[task_rd_adr_i[21:2]];
end
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_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
 
*/
always@(posedge CLK_I)
always@(posedge CLK_I)
begin
begin
    if (wr_sel)
    if (CYC_I && STB_I && WE_I && ACK_O)
    begin
            wr_mem(ADR_I, DAT_I, SEL_I) ;
        mem_wr_data_out         = wb_memory[ADR_I[11:2]] ;
 
 
 
        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[11:2]] <= mem_wr_data_out ;
 
    end
 
end
end
 
 
endmodule
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.