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

Subversion Repositories gpio

[/] [gpio/] [trunk/] [bench/] [verilog/] [wb_master.v] - Diff between revs 37 and 65

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 37 Rev 65
`include "timescale.v"
`include "timescale.v"
`include "gpio_defines.v"
`include "gpio_defines.v"
 
 
//                              -*- Mode: Verilog -*-
//                              -*- Mode: Verilog -*-
// Filename        : wb_master.v
// Filename        : wb_master.v
// Description     : Wishbone Master Behavorial
// Description     : Wishbone Master Behavorial
// Author          : Winefred Washington
// Author          : Winefred Washington
// Created On      : Thu Jan 11 21:18:41 2001
// Created On      : Thu Jan 11 21:18:41 2001
// Last Modified By: .
// Last Modified By: .
// Last Modified On: .
// Last Modified On: .
// Update Count    : 0
// Update Count    : 0
// Status          : Unknown, Use with caution!
// Status          : Unknown, Use with caution!
 
 
//        Description                   Specification
//        Description                   Specification
// General Description:            8, 16, 32-bit WISHBONE Master
// General Description:            8, 16, 32-bit WISHBONE Master
// Supported cycles:               MASTER, READ/WRITE
// Supported cycles:               MASTER, READ/WRITE
//                                 MASTER, BLOCK READ/WRITE
//                                 MASTER, BLOCK READ/WRITE
//                                 MASTER, RMW
//                                 MASTER, RMW
// Data port, size:                8, 16, 32-bit
// Data port, size:                8, 16, 32-bit
// Data port, granularity          8-bit
// Data port, granularity          8-bit
// Data port, Max. operand size    32-bit
// Data port, Max. operand size    32-bit
// Data transfer ordering:         little endian
// Data transfer ordering:         little endian
// Data transfer sequencing:       undefined
// Data transfer sequencing:       undefined
//
//
 
 
module wb_master(CLK_I, RST_I, TAG_I, TAG_O,
module wb_master(CLK_I, RST_I, TAG_I, TAG_O,
                   ACK_I, ADR_O, CYC_O, DAT_I, DAT_O, ERR_I, RTY_I, SEL_O, STB_O, WE_O);
                   ACK_I, ADR_O, CYC_O, DAT_I, DAT_O, ERR_I, RTY_I, SEL_O, STB_O, WE_O);
 
 
parameter aw = `GPIO_ADDRHH+1 ;
parameter aw = `GPIO_ADDRHH+1 ;
   input                CLK_I;
   input                CLK_I;
   input                RST_I;
   input                RST_I;
   input [3:0]           TAG_I;
   input [3:0]           TAG_I;
   output [3:0]  TAG_O;
   output [3:0]  TAG_O;
   input                ACK_I;
   input                ACK_I;
   output [aw-1:0]       ADR_O;
   output [aw-1:0]       ADR_O;
   output               CYC_O;
   output               CYC_O;
   input [31:0]  DAT_I;
   input [31:0]  DAT_I;
   output [31:0]         DAT_O;
   output [31:0]         DAT_O;
   input                ERR_I;
   input                ERR_I;
   input                RTY_I;
   input                RTY_I;
   output [3:0]  SEL_O;
   output [3:0]  SEL_O;
   output               STB_O;
   output               STB_O;
   output               WE_O;
   output               WE_O;
 
 
   reg [aw-1:0]          ADR_O;
   reg [aw-1:0]          ADR_O;
   reg [3:0]             SEL_O;
   reg [3:0]             SEL_O;
   reg                  CYC_O;
   reg                  CYC_O;
   reg                  STB_O;
   reg                  STB_O;
   reg                  WE_O;
   reg                  WE_O;
   reg [31:0]            DAT_O;
   reg [31:0]            DAT_O;
 
 
   wire [15:0]           mem_sizes;      // determines the data width of an address range
   wire [15:0]           mem_sizes;      // determines the data width of an address range
   reg [31:0]            write_burst_buffer[0:7];
   reg [31:0]            write_burst_buffer[0:7];
   reg [31:0]            read_burst_buffer[0:7];
   reg [31:0]            read_burst_buffer[0:7];
 
 
   reg                  GO;
   reg                  GO;
   integer              cycle_end;
   integer              cycle_end;
   integer              address;
   integer              address;
   integer              data;
   integer              data;
   integer              selects;
   integer              selects;
   integer              write_flag;
   integer              write_flag;
 
 
   //
   //
   // mem_sizes determines the data widths of memory space
   // mem_sizes determines the data widths of memory space
   // The memory space is divided into eight regions. Each
   // The memory space is divided into eight regions. Each
   // region is controlled by a two bit field.
   // region is controlled by a two bit field.
   //
   //
   //    Bits
   //    Bits
   //    00 = 8 bit memory space
   //    00 = 8 bit memory space
   //    01 = 16 bit 
   //    01 = 16 bit 
   //    10 = 32 bit
   //    10 = 32 bit
   //    11 = 64 bit (not supported in this model
   //    11 = 64 bit (not supported in this model
   //
   //
 
 
   assign               mem_sizes = 16'b10_01_10_11_00_01_10_11;
   assign               mem_sizes = 16'b10_01_10_11_00_01_10_11;
 
 
   function [1:0] data_width;
   function [1:0] data_width;
      input [31:0] adr;
      input [31:0] adr;
      begin
      begin
         casex (adr[31:29])
         casex (adr[31:29])
           3'b000: data_width = mem_sizes[15:14];
           3'b000: data_width = mem_sizes[15:14];
           3'b001: data_width = mem_sizes[13:12];
           3'b001: data_width = mem_sizes[13:12];
           3'b010: data_width = mem_sizes[11:10];
           3'b010: data_width = mem_sizes[11:10];
           3'b011: data_width = mem_sizes[9:8];
           3'b011: data_width = mem_sizes[9:8];
           3'b100: data_width = mem_sizes[7:6];
           3'b100: data_width = mem_sizes[7:6];
           3'b101: data_width = mem_sizes[5:4];
           3'b101: data_width = mem_sizes[5:4];
           3'b110: data_width = mem_sizes[3:2];
           3'b110: data_width = mem_sizes[3:2];
           3'b111: data_width = mem_sizes[1:0];
           3'b111: data_width = mem_sizes[1:0];
           3'bxxx: data_width = 2'bxx;
           3'bxxx: data_width = 2'bxx;
         endcase // casex (adr[31:29])
         endcase // casex (adr[31:29])
      end
      end
   endfunction
   endfunction
 
 
   always @(posedge CLK_I or posedge RST_I)
   always @(posedge CLK_I or posedge RST_I)
     begin
     begin
        if (RST_I)
        if (RST_I)
          begin
          begin
             GO = 1'b0;
             GO = 1'b0;
          end
          end
     end
     end
 
 
   // read single
   // read single
   task rd;
   task rd;
      input [31:0] adr;
      input [31:0] adr;
      output [31:0] result;
      output [31:0] result;
 
 
      begin
      begin
         cycle_end = 1;
         cycle_end = 1;
         address = adr;
         address = adr;
         selects = 255;
         selects = 255;
         write_flag = 0;
         write_flag = 0;
 
 
         GO <= 1;
         GO <= 1;
         @(posedge CLK_I);
         @(posedge CLK_I);
//       GO <= 0;        
//       GO <= 0;        
 
 
         // wait for cycle to start
         // wait for cycle to start
         while (~CYC_O)
         while (~CYC_O)
           @(posedge CLK_I);
           @(posedge CLK_I);
 
 
         // wait for cycle to end
         // wait for cycle to end
         while (CYC_O)
         while (CYC_O)
           @(posedge CLK_I);
           @(posedge CLK_I);
 
 
         result = data;
         result = data;
//      $display(" Reading %h from address %h", result, address);
//      $display(" Reading %h from address %h", result, address);
 
 
      end
      end
   endtask // read
   endtask // read
 
 
   task wr;
   task wr;
      input [31:0] adr;
      input [31:0] adr;
      input [31:0] dat;
      input [31:0] dat;
      input [3:0] sel;
      input [3:0] sel;
      begin
      begin
         cycle_end = 1;
         cycle_end = 1;
         address = adr;
         address = adr;
         selects = sel;
         selects = sel;
         write_flag = 1;
         write_flag = 1;
         data = dat;
         data = dat;
 
 
         GO <= 1;
         GO <= 1;
         @(posedge CLK_I);
         @(posedge CLK_I);
//       GO <= 0;        
//       GO <= 0;        
 
 
         // wait for cycle to start
         // wait for cycle to start
         while (~CYC_O)
         while (~CYC_O)
           @(posedge CLK_I);
           @(posedge CLK_I);
 
 
         // wait for cycle to end
         // wait for cycle to end
         while (CYC_O)
         while (CYC_O)
           @(posedge CLK_I);
           @(posedge CLK_I);
//      $display(" Writing %h to address %h", data, address);
//      $display(" Writing %h to address %h", data, address);
 
 
      end
      end
   endtask // wr
   endtask // wr
 
 
   // block read
   // block read
   task blkrd;
   task blkrd;
      input [31:0] adr;
      input [31:0] adr;
      input end_flag;
      input end_flag;
      output [31:0] result;
      output [31:0] result;
 
 
      begin
      begin
         write_flag = 0;
         write_flag = 0;
         cycle_end = end_flag;
         cycle_end = end_flag;
         address = adr;
         address = adr;
         GO <= 1;
         GO <= 1;
         @(posedge CLK_I);
         @(posedge CLK_I);
//       GO <= 0;        
//       GO <= 0;        
 
 
         while (~(ACK_I & STB_O))
         while (~(ACK_I & STB_O))
           @(posedge CLK_I);
           @(posedge CLK_I);
 
 
         result = data;
         result = data;
      end
      end
   endtask // blkrd
   endtask // blkrd
 
 
   // block write
   // block write
   task blkwr;
   task blkwr;
      input [31:0] adr;
      input [31:0] adr;
      input [31:0] dat;
      input [31:0] dat;
      input [3:0] sel;
      input [3:0] sel;
      input end_flag;
      input end_flag;
      begin
      begin
         write_flag = 1;
         write_flag = 1;
         cycle_end = end_flag;
         cycle_end = end_flag;
         address = adr;
         address = adr;
         data = dat;
         data = dat;
         selects = sel;
         selects = sel;
         GO <= 1;
         GO <= 1;
         @(posedge CLK_I);
         @(posedge CLK_I);
//       GO <= 0;        
//       GO <= 0;        
 
 
         while (~(ACK_I & STB_O))
         while (~(ACK_I & STB_O))
           @(posedge CLK_I);
           @(posedge CLK_I);
 
 
      end
      end
   endtask // blkwr
   endtask // blkwr
 
 
   // RMW
   // RMW
   task rmw;
   task rmw;
      input [31:0] adr;
      input [31:0] adr;
      input [31:0] dat;
      input [31:0] dat;
      input [3:0] sel;
      input [3:0] sel;
      output [31:0] result;
      output [31:0] result;
 
 
      begin
      begin
         // read phase
         // read phase
         write_flag = 0;
         write_flag = 0;
         cycle_end = 0;
         cycle_end = 0;
         address = adr;
         address = adr;
         GO <= 1;
         GO <= 1;
         @(posedge CLK_I);
         @(posedge CLK_I);
//       GO <= 0;        
//       GO <= 0;        
 
 
         while (~(ACK_I & STB_O))
         while (~(ACK_I & STB_O))
           @(posedge CLK_I);
           @(posedge CLK_I);
 
 
         result = data;
         result = data;
 
 
         // write phase
         // write phase
         write_flag = 1;
         write_flag = 1;
         address = adr;
         address = adr;
         selects = sel;
         selects = sel;
         GO <= 1;
         GO <= 1;
         data <= dat;
         data <= dat;
         cycle_end <= 1;
         cycle_end <= 1;
         @(posedge CLK_I);
         @(posedge CLK_I);
//       GO <= 0;        
//       GO <= 0;        
 
 
         while (~(ACK_I & STB_O))
         while (~(ACK_I & STB_O))
           @(posedge CLK_I);
           @(posedge CLK_I);
 
 
      end
      end
   endtask // rmw
   endtask // rmw
 
 
   always @(posedge CLK_I)
   always @(posedge CLK_I)
     begin
     begin
        if (RST_I)
        if (RST_I)
          ADR_O <= 32'h0000_0000;
          ADR_O <= 32'h0000_0000;
        else
        else
          ADR_O <= address;
          ADR_O <= address;
     end
     end
 
 
   always @(posedge CLK_I)
   always @(posedge CLK_I)
     begin
     begin
        if (RST_I | ERR_I | RTY_I)
        if (RST_I | ERR_I | RTY_I)
          CYC_O <= 1'b0;
          CYC_O <= 1'b0;
        else if ((cycle_end == 1) & ACK_I)
        else if ((cycle_end == 1) & ACK_I)
          CYC_O <= 1'b0;
          CYC_O <= 1'b0;
        else if (GO | CYC_O) begin
        else if (GO | CYC_O) begin
          CYC_O <= 1'b1;
          CYC_O <= 1'b1;
          GO <= 1'b0;
          GO <= 1'b0;
        end
        end
     end
     end
 
 
   // stb control
   // stb control
   always @(posedge CLK_I)
   always @(posedge CLK_I)
     begin
     begin
        if (RST_I | ERR_I | RTY_I)
        if (RST_I | ERR_I | RTY_I)
          STB_O <= 1'b0;
          STB_O <= 1'b0;
        else if (STB_O & ACK_I)
        else if (STB_O & ACK_I)
          STB_O <= 1'b0;
          STB_O <= 1'b0;
        else if (GO | STB_O)
        else if (GO | STB_O)
          STB_O <= 1'b1;
          STB_O <= 1'b1;
     end
     end
 
 
   // selects & data
   // selects & data
   always @(posedge CLK_I)
   always @(posedge CLK_I)
     begin
     begin
        if (write_flag == 0) begin
        if (write_flag == 0) begin
           SEL_O <= 4'b1111;
           SEL_O <= 4'b1111;
           if (STB_O & ACK_I)
           if (STB_O & ACK_I)
             data <= DAT_I;
             data <= DAT_I;
        end
        end
        else begin
        else begin
           case (data_width(address))
           case (data_width(address))
             2'b00: begin
             2'b00: begin
                SEL_O <= {3'b000, selects[0]};
                SEL_O <= {3'b000, selects[0]};
                DAT_O <= {data[7:0], data[7:0], data[7:0], data[7:0]};
                DAT_O <= {data[7:0], data[7:0], data[7:0], data[7:0]};
             end
             end
             2'b01: begin
             2'b01: begin
                SEL_O <= {2'b00, selects[1:0]};
                SEL_O <= {2'b00, selects[1:0]};
                DAT_O <= {data[15:0], data[15:0]};
                DAT_O <= {data[15:0], data[15:0]};
             end
             end
             2'b10: begin
             2'b10: begin
                SEL_O <= selects;
                SEL_O <= selects;
                DAT_O <= data;
                DAT_O <= data;
             end
             end
           endcase
           endcase
        end
        end
     end
     end
 
 
   always @(posedge CLK_I)
   always @(posedge CLK_I)
     begin
     begin
        if (RST_I)
        if (RST_I)
          WE_O <= 1'b0;
          WE_O <= 1'b0;
        else if (GO)
        else if (GO)
          WE_O <= write_flag;
          WE_O <= write_flag;
     end
     end
 
 
endmodule
endmodule
 
 
 
 
 
 
 
 
 
 
 
 

powered by: WebSVN 2.1.0

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