forked from Github_Repos/cvw
		
	Added ahbapbbridge and cleaning RAM
This commit is contained in:
		
							parent
							
								
									a190342b8a
								
							
						
					
					
						commit
						9e5ab4d378
					
				@ -44,7 +44,7 @@ module bram1p1rw
 | 
			
		||||
	//----------------------------------------------------------------------
 | 
			
		||||
	) (
 | 
			
		||||
	   input logic 					 clk,
 | 
			
		||||
	   input logic 					 ena,
 | 
			
		||||
	   input logic 					 en,
 | 
			
		||||
	   input logic [NUM_COL-1:0] 	 we,
 | 
			
		||||
	   input logic [ADDR_WIDTH-1:0]  addr,
 | 
			
		||||
	   output logic [DATA_WIDTH-1:0] dout,
 | 
			
		||||
@ -60,7 +60,7 @@ module bram1p1rw
 | 
			
		||||
 | 
			
		||||
  always @ (posedge clk) begin
 | 
			
		||||
	dout <= RAM[addr];    
 | 
			
		||||
	if(ena) begin
 | 
			
		||||
	if(en) begin
 | 
			
		||||
	  for(i=0;i<NUM_COL;i=i+1) begin
 | 
			
		||||
		if(we[i]) begin
 | 
			
		||||
		  RAM[addr][i*COL_WIDTH +: COL_WIDTH] <= din[i*COL_WIDTH +:COL_WIDTH];
 | 
			
		||||
 | 
			
		||||
@ -42,27 +42,7 @@ module simpleram #(parameter BASE=0, RANGE = 65535) (
 | 
			
		||||
  localparam ADDR_WDITH = $clog2(RANGE/8);
 | 
			
		||||
  localparam OFFSET = $clog2(`XLEN/8);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  bram1p1rw #(`XLEN/8, 8, ADDR_WDITH) 
 | 
			
		||||
  memory(.clk, .ena(we), .we(ByteMask), .addr(a[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(rd), .din(wd));
 | 
			
		||||
  
 | 
			
		||||
/* -----\/----- EXCLUDED -----\/-----
 | 
			
		||||
  logic [`XLEN-1:0] RAM[BASE>>(1+`XLEN/32):(RANGE+BASE)>>1+(`XLEN/32)];
 | 
			
		||||
  
 | 
			
		||||
  // discard bottom 2 or 3 bits of address offset within word or doubleword
 | 
			
		||||
  localparam adrlsb = (`XLEN==64) ? 3 : 2;
 | 
			
		||||
  logic [31:adrlsb] adrmsbs;
 | 
			
		||||
  assign adrmsbs = a[31:adrlsb];
 | 
			
		||||
 | 
			
		||||
  always_ff @(posedge clk)
 | 
			
		||||
    rd <= RAM[adrmsbs];
 | 
			
		||||
 | 
			
		||||
  genvar            index;
 | 
			
		||||
  for(index = 0; index < `XLEN/8; index++) begin
 | 
			
		||||
    always_ff @(posedge clk) begin
 | 
			
		||||
      if (we & ByteMask[index]) RAM[adrmsbs][8*(index+1)-1:8*index] <= #1 wd[8*(index+1)-1:8*index];
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 -----/\----- EXCLUDED -----/\----- */
 | 
			
		||||
    memory(.clk, .en(we), .we(ByteMask), .addr(a[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(rd), .din(wd));
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										98
									
								
								pipelined/src/uncore/ahbapbbridge.sv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								pipelined/src/uncore/ahbapbbridge.sv
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,98 @@
 | 
			
		||||
///////////////////////////////////////////
 | 
			
		||||
// ahbapbbridge.sv
 | 
			
		||||
//
 | 
			
		||||
// Written: David_Harris@hmc.edu & Nic Lucio 7 June 2022
 | 
			
		||||
//
 | 
			
		||||
// Purpose: AHB to APB bridge
 | 
			
		||||
// 
 | 
			
		||||
// A component of the Wally configurable RISC-V project.
 | 
			
		||||
// 
 | 
			
		||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
 | 
			
		||||
//
 | 
			
		||||
// MIT LICENSE
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this 
 | 
			
		||||
// software and associated documentation files (the "Software"), to deal in the Software 
 | 
			
		||||
// without restriction, including without limitation the rights to use, copy, modify, merge, 
 | 
			
		||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons 
 | 
			
		||||
// to whom the Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
//   The above copyright notice and this permission notice shall be included in all copies or 
 | 
			
		||||
//   substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
 | 
			
		||||
//   INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
 | 
			
		||||
//   PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
 | 
			
		||||
//   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
 | 
			
		||||
//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 
 | 
			
		||||
//   OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
`include "wally-config.vh"
 | 
			
		||||
 | 
			
		||||
module ahbapbbridge #(PERIPHS = 2) (
 | 
			
		||||
  input  logic             HCLK, HRESETn,
 | 
			
		||||
  input  logic [PERIPHS-1:0] HSEL,  
 | 
			
		||||
  input  logic [31:0]      HADDR, 
 | 
			
		||||
  input  logic [`XLEN-1:0] HWDATA,
 | 
			
		||||
  input  logic             HWRITE,
 | 
			
		||||
  input  logic [1:0]       HTRANS,
 | 
			
		||||
  input  logic             HREADY,
 | 
			
		||||
  output logic [`XLEN-1:0] HRDATA,
 | 
			
		||||
  output logic             HRESP, HREADYOUT,
 | 
			
		||||
  output logic             PCLK, PRESETn,
 | 
			
		||||
  output logic [PERIPHS-1:0] PSEL,
 | 
			
		||||
  output logic             PWRITE,
 | 
			
		||||
  output logic             PENABLE,
 | 
			
		||||
  output logic [31:0]      PADDR,
 | 
			
		||||
  output logic [`XLEN-1:0] PWDATA,
 | 
			
		||||
  input  logic [PERIPHS-1:0] PREADY,
 | 
			
		||||
  input  var   [`XLEN-1:0][PERIPHS-1:0] PRDATA
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
  logic activeTrans;
 | 
			
		||||
  logic initTrans, initTransSel, initTransSelD;
 | 
			
		||||
  logic nextPENABLE;
 | 
			
		||||
 | 
			
		||||
  // convert AHB to APB signals
 | 
			
		||||
  assign PCLK = HCLK;
 | 
			
		||||
  assign PRESETn = HRESETn;
 | 
			
		||||
 | 
			
		||||
  // identify start of a transaction
 | 
			
		||||
  assign activeTrans = (HTRANS == 2'b10); // only accept nonsequential transactions
 | 
			
		||||
  assign initTrans = activeTrans & HREADY;  // start a transaction when the bus is ready and an active transaction is requested
 | 
			
		||||
  assign initTransSel = initTrans & |HSEL; // capture data and address if any of the peripherals are selected
 | 
			
		||||
 | 
			
		||||
  // delay AHB Address phase signals to align with AHB Data phase because APB expects them at the same time
 | 
			
		||||
  flopenr #(32) addrreg(HCLK, ~HRESETn, initTransSel, HADDR, PADDR);
 | 
			
		||||
  flopenr #(1) writereg(HCLK, ~HRESETn, initTransSel, HWRITE, PWRITE);
 | 
			
		||||
  // enable selreg with iniTrans rather than initTransSel so PSEL can turn off
 | 
			
		||||
  flopenr #(PERIPHS) selreg(HCLK, ~HRESETn, initTrans, HSEL & {PERIPHS{activeTrans}}, PSEL); 
 | 
			
		||||
  // AHB Data phase signal doesn't need delay.  Note that HWDATA is guaranteed to remain stable until READY is asserted
 | 
			
		||||
  assign PWDATA = HWDATA;
 | 
			
		||||
 | 
			
		||||
  // enable logic: goes high a cycle after initTrans, then back low on cycle after desired PREADY is asserted
 | 
			
		||||
  // cycle1: AHB puts HADDR, HWRITE, HSEL on bus.  initTrans is 1, and these are captured
 | 
			
		||||
  // cycle2: AHB puts HWDATA on the bus.  This effectively extends the setup phase
 | 
			
		||||
  // cycle3: bridge raises PENABLE.  Peripheral typically responds with PREADY.  
 | 
			
		||||
  //         Read occurs by end of cycle.  Write occurs at end of cycle.
 | 
			
		||||
  flopr #(1) inittransreg(HCLK, ~HRESETn, initTransSel, initTransSelD);
 | 
			
		||||
  assign nextPENABLE = PENABLE ? ~HREADY : initTransSelD; 
 | 
			
		||||
  flopr #(1) enablereg(HCLK, ~HRESETn, nextPENABLE, PENABLE);
 | 
			
		||||
 | 
			
		||||
  // result and ready multiplexer 
 | 
			
		||||
  int i;
 | 
			
		||||
  always_comb
 | 
			
		||||
    for (i=0; i<PERIPHS; i++)  begin
 | 
			
		||||
      // no peripheral selected: read 0, indicate ready
 | 
			
		||||
      HRDATA = 0;
 | 
			
		||||
      HREADYOUT = 1;
 | 
			
		||||
      if (PSEL[i]) begin // highest numbered peripheral has priority, but multiple PSEL should never be asserted
 | 
			
		||||
          HRDATA = PRDATA[i];
 | 
			
		||||
          HREADYOUT = PREADY[i];
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
  // resp logic
 | 
			
		||||
  assign HRESP = 0; // bridge never indicates errors
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										146
									
								
								pipelined/src/uncore/gpio_apb.sv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								pipelined/src/uncore/gpio_apb.sv
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,146 @@
 | 
			
		||||
///////////////////////////////////////////
 | 
			
		||||
// gpio_apb.sv
 | 
			
		||||
//
 | 
			
		||||
// Written: David_Harris@hmc.edu 14 January 2021
 | 
			
		||||
// Modified: bbracker@hmc.edu 15 Apr. 2021
 | 
			
		||||
//
 | 
			
		||||
// Purpose: General Purpose I/O peripheral
 | 
			
		||||
//   See FE310-G002-Manual-v19p05 for specifications
 | 
			
		||||
//   No interrupts, drive strength, or pull-ups supported
 | 
			
		||||
// 
 | 
			
		||||
// A component of the Wally configurable RISC-V project.
 | 
			
		||||
// 
 | 
			
		||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
 | 
			
		||||
//
 | 
			
		||||
// MIT LICENSE
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this 
 | 
			
		||||
// software and associated documentation files (the "Software"), to deal in the Software 
 | 
			
		||||
// without restriction, including without limitation the rights to use, copy, modify, merge, 
 | 
			
		||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons 
 | 
			
		||||
// to whom the Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
//   The above copyright notice and this permission notice shall be included in all copies or 
 | 
			
		||||
//   substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
 | 
			
		||||
//   INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
 | 
			
		||||
//   PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
 | 
			
		||||
//   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
 | 
			
		||||
//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 
 | 
			
		||||
//   OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
`include "wally-config.vh"
 | 
			
		||||
 | 
			
		||||
module gpio_apb (
 | 
			
		||||
  input  logic             PCLK, PRESETn,
 | 
			
		||||
  input  logic             PSEL,
 | 
			
		||||
  input  logic [7:0]       PADDR, 
 | 
			
		||||
  input  logic [`XLEN-1:0] PWDATA,
 | 
			
		||||
  input  logic             PWRITE,
 | 
			
		||||
  input  logic             PENABLE,
 | 
			
		||||
  output logic [`XLEN-1:0] PRDATA,
 | 
			
		||||
  output logic             PREADY,
 | 
			
		||||
  input  logic [31:0]      GPIOPinsIn,
 | 
			
		||||
  output logic [31:0]      GPIOPinsOut, GPIOPinsEn,
 | 
			
		||||
  output logic             GPIOIntr);
 | 
			
		||||
 | 
			
		||||
  logic [31:0] input0d, input1d, input2d, input3d;
 | 
			
		||||
  logic [31:0] input_val, input_en, output_en, output_val;
 | 
			
		||||
  logic [31:0] rise_ie, rise_ip, fall_ie, fall_ip, high_ie, high_ip, low_ie, low_ip; 
 | 
			
		||||
 | 
			
		||||
  logic [7:0] entry;
 | 
			
		||||
  logic [31:0] Din, Dout;
 | 
			
		||||
  logic memwrite;
 | 
			
		||||
  
 | 
			
		||||
  // APB I/O
 | 
			
		||||
  assign entry = {PADDR[7:2],2'b00};  // 32-bit word-aligned accesses
 | 
			
		||||
  assign memwrite = PWRITE & PENABLE;  // only write in access phase
 | 
			
		||||
  assign PREADY = PENABLE; // GPIO never takes >1 cycle to respond
 | 
			
		||||
 | 
			
		||||
  // account for subword read/write circuitry
 | 
			
		||||
  // -- Note GPIO registers are 32 bits no matter what; access them with LW SW.
 | 
			
		||||
  //    (At least that's what I think when FE310 spec says "only naturally aligned 32-bit accesses are supported")
 | 
			
		||||
  if (`XLEN == 64) begin
 | 
			
		||||
    assign Din =    entry[2] ? PWDATA[63:32] : PWDATA[31:0];
 | 
			
		||||
    assign PRDATA = entry[2] ? {Dout,32'b0}  : {32'b0,Dout};
 | 
			
		||||
  end else begin // 32-bit
 | 
			
		||||
    assign Din = PWDATA[31:0];
 | 
			
		||||
    assign PRDATA = Dout;
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  // register access
 | 
			
		||||
  always_ff @(posedge PCLK, negedge PRESETn)
 | 
			
		||||
    if (~PRESETn) begin // asynch reset
 | 
			
		||||
      input_en <= 0;
 | 
			
		||||
      output_en <= 0;
 | 
			
		||||
      // *** synch reset not yet implemented [DH: can we delete this comment?  Check if a sync reset is required]
 | 
			
		||||
      output_val <= #1 0;
 | 
			
		||||
      rise_ie <= #1 0;
 | 
			
		||||
      rise_ip <= #1 0;
 | 
			
		||||
      fall_ie <= #1 0;
 | 
			
		||||
      fall_ip <= #1 0;
 | 
			
		||||
      high_ie <= #1 0;
 | 
			
		||||
      high_ip <= #1 0;
 | 
			
		||||
      low_ie <= #1 0;
 | 
			
		||||
      low_ip <= #1 0;
 | 
			
		||||
    end else begin     // writes
 | 
			
		||||
        // According to FE310 spec: Once the interrupt is pending, it will remain set until a 1 is written to the *_ip register at that bit.
 | 
			
		||||
        /* verilator lint_off CASEINCOMPLETE */
 | 
			
		||||
      if (memwrite) 
 | 
			
		||||
        case(entry)
 | 
			
		||||
          8'h04: input_en <= #1 Din;
 | 
			
		||||
          8'h08: output_en <= #1 Din;
 | 
			
		||||
          8'h0C: output_val <= #1 Din;
 | 
			
		||||
          8'h18: rise_ie <= #1 Din;
 | 
			
		||||
          8'h20: fall_ie <= #1 Din;
 | 
			
		||||
          8'h28: high_ie <= #1 Din;
 | 
			
		||||
          8'h30: low_ie  <= #1 Din;
 | 
			
		||||
          8'h40: output_val <= #1 output_val ^ Din; // OUT_XOR
 | 
			
		||||
        endcase
 | 
			
		||||
        /* verilator lint_on CASEINCOMPLETE */
 | 
			
		||||
 | 
			
		||||
      // interrupts can be cleared by writing corresponding bits to a register
 | 
			
		||||
      if (memwrite & entry == 8'h1C)   rise_ip <= rise_ip & ~Din;
 | 
			
		||||
      else                             rise_ip <= rise_ip | (input2d & ~input3d);
 | 
			
		||||
      if (memwrite & (entry == 8'h24)) fall_ip <= fall_ip & ~Din;
 | 
			
		||||
      else                             fall_ip <= fall_ip | (~input2d & input3d);
 | 
			
		||||
      if (memwrite & (entry == 8'h2C)) high_ip <= high_ip & ~Din;
 | 
			
		||||
      else                             high_ip <= high_ip | input3d;
 | 
			
		||||
      if (memwrite & (entry == 8'h34)) low_ip  <= low_ip  & ~Din;
 | 
			
		||||
      else                             low_ip  <= low_ip  | ~input3d;
 | 
			
		||||
 | 
			
		||||
      case(entry) // flop to sample inputs
 | 
			
		||||
        8'h00: Dout <= #1 input_val;
 | 
			
		||||
        8'h04: Dout <= #1 input_en;
 | 
			
		||||
        8'h08: Dout <= #1 output_en;
 | 
			
		||||
        8'h0C: Dout <= #1 output_val;
 | 
			
		||||
        8'h18: Dout <= #1 rise_ie;
 | 
			
		||||
        8'h1C: Dout <= #1 rise_ip;
 | 
			
		||||
        8'h20: Dout <= #1 fall_ie;
 | 
			
		||||
        8'h24: Dout <= #1 fall_ip;
 | 
			
		||||
        8'h28: Dout <= #1 high_ie;
 | 
			
		||||
        8'h2C: Dout <= #1 high_ip;
 | 
			
		||||
        8'h30: Dout <= #1 low_ie;
 | 
			
		||||
        8'h34: Dout <= #1 low_ip;
 | 
			
		||||
        8'h40: Dout <= #1 0; // OUT_XOR reads as 0
 | 
			
		||||
        default: Dout <= #1 0;
 | 
			
		||||
      endcase
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
  // chip i/o
 | 
			
		||||
  // connect OUT to IN for loopback testing
 | 
			
		||||
  if (`GPIO_LOOPBACK_TEST) assign input0d = ((output_en & GPIOPinsOut) | (~output_en & GPIOPinsIn)) & input_en;
 | 
			
		||||
  else                     assign input0d = GPIOPinsIn & input_en;
 | 
			
		||||
 | 
			
		||||
  // synchroninzer for inputs
 | 
			
		||||
  flop #(32) sync1(PCLK,input0d,input1d);
 | 
			
		||||
  flop #(32) sync2(PCLK,input1d,input2d);
 | 
			
		||||
  flop #(32) sync3(PCLK,input2d,input3d);
 | 
			
		||||
  assign input_val = input3d;
 | 
			
		||||
  assign GPIOPinsOut = output_val;
 | 
			
		||||
  assign GPIOPinsEn = output_en;
 | 
			
		||||
 | 
			
		||||
  assign GPIOIntr = |{(rise_ip & rise_ie),(fall_ip & fall_ie),(high_ip & high_ie),(low_ip & low_ie)};
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
@ -63,6 +63,7 @@ module ram #(parameter BASE=0, RANGE = 65535) (
 | 
			
		||||
  // *** this seems like a weird way to use reset
 | 
			
		||||
  flopenr #(1) memwritereg(HCLK, 1'b0, initTrans | ~HRESETn, HSELRam &  HWRITE, memwrite);
 | 
			
		||||
  flopenr #(32)   haddrreg(HCLK, 1'b0, initTrans | ~HRESETn, HADDR, A);
 | 
			
		||||
  
 | 
			
		||||
  // busy FSM to extend READY signal
 | 
			
		||||
  always @(posedge HCLK, negedge HRESETn) 
 | 
			
		||||
    if (~HRESETn) begin
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										107
									
								
								pipelined/src/uncore/ram_orig.sv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								pipelined/src/uncore/ram_orig.sv
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,107 @@
 | 
			
		||||
///////////////////////////////////////////
 | 
			
		||||
// ram_orig.sv
 | 
			
		||||
//
 | 
			
		||||
// Written: David_Harris@hmc.edu 9 January 2021
 | 
			
		||||
// Modified: 
 | 
			
		||||
//
 | 
			
		||||
// Purpose: On-chip RAM, external to core
 | 
			
		||||
// 
 | 
			
		||||
// A component of the Wally configurable RISC-V project.
 | 
			
		||||
// 
 | 
			
		||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
 | 
			
		||||
//
 | 
			
		||||
// MIT LICENSE
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this 
 | 
			
		||||
// software and associated documentation files (the "Software"), to deal in the Software 
 | 
			
		||||
// without restriction, including without limitation the rights to use, copy, modify, merge, 
 | 
			
		||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons 
 | 
			
		||||
// to whom the Software is furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
//   The above copyright notice and this permission notice shall be included in all copies or 
 | 
			
		||||
//   substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
 | 
			
		||||
//   INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
 | 
			
		||||
//   PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
 | 
			
		||||
//   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
 | 
			
		||||
//   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 
 | 
			
		||||
//   OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
`include "wally-config.vh"
 | 
			
		||||
 | 
			
		||||
module ram_orig #(parameter BASE=0, RANGE = 65535) (
 | 
			
		||||
  input  logic             HCLK, HRESETn, 
 | 
			
		||||
  input  logic             HSELRam,
 | 
			
		||||
  input  logic [31:0]      HADDR,
 | 
			
		||||
  input  logic             HWRITE,
 | 
			
		||||
  input  logic             HREADY,
 | 
			
		||||
  input  logic [1:0]       HTRANS,
 | 
			
		||||
  input  logic [`XLEN-1:0] HWDATA,
 | 
			
		||||
  input  logic [3:0]       HSIZED,
 | 
			
		||||
  output logic [`XLEN-1:0] HREADRam,
 | 
			
		||||
  output logic             HRESPRam, HREADYRam
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
  // Desired changes.
 | 
			
		||||
  // 1. find a way to merge read and write address into 1 port.
 | 
			
		||||
  // 2. remove all unnecessary latencies. (HREADY needs to be able to constant high.)
 | 
			
		||||
  // 3. implement burst.
 | 
			
		||||
  // 4. remove the configurable latency.
 | 
			
		||||
 | 
			
		||||
  logic [`XLEN/8-1:0] 		  ByteMaskM;
 | 
			
		||||
  logic [31:0]        HWADDR, A;
 | 
			
		||||
  logic				  prevHREADYRam, risingHREADYRam;
 | 
			
		||||
  logic				  initTrans;
 | 
			
		||||
  logic				  memwrite;
 | 
			
		||||
  logic [3:0] 		  busycount;
 | 
			
		||||
  
 | 
			
		||||
  swbytemask swbytemask(.Size(HSIZED[1:0]), .Adr(HWADDR[2:0]), .ByteMask(ByteMaskM));
 | 
			
		||||
 | 
			
		||||
  assign initTrans = HREADY & HSELRam & (HTRANS != 2'b00);
 | 
			
		||||
 | 
			
		||||
  // *** this seems like a weird way to use reset
 | 
			
		||||
  flopenr #(1) memwritereg(HCLK, 1'b0, initTrans | ~HRESETn, HSELRam &  HWRITE, memwrite);
 | 
			
		||||
  flopenr #(32)   haddrreg(HCLK, 1'b0, initTrans | ~HRESETn, HADDR, A);
 | 
			
		||||
  
 | 
			
		||||
  // busy FSM to extend READY signal
 | 
			
		||||
  always @(posedge HCLK, negedge HRESETn) 
 | 
			
		||||
    if (~HRESETn) begin
 | 
			
		||||
      busycount <= 0;
 | 
			
		||||
      HREADYRam <= #1 0;
 | 
			
		||||
    end else begin
 | 
			
		||||
      if (initTrans) begin
 | 
			
		||||
        busycount <= 0;
 | 
			
		||||
        HREADYRam <= #1 0;
 | 
			
		||||
      end else if (~HREADYRam) begin
 | 
			
		||||
        if (busycount == 0) begin // Ram latency, for testing purposes.  *** test with different values such as 2
 | 
			
		||||
          HREADYRam <= #1 1;
 | 
			
		||||
        end else begin
 | 
			
		||||
          busycount <= busycount + 1;
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  assign HRESPRam = 0; // OK
 | 
			
		||||
 | 
			
		||||
  localparam ADDR_WDITH = $clog2(RANGE/8);
 | 
			
		||||
  localparam OFFSET = $clog2(`XLEN/8);
 | 
			
		||||
  
 | 
			
		||||
  // Rising HREADY edge detector
 | 
			
		||||
  //   Indicates when ram is finishing up
 | 
			
		||||
  //   Needed because HREADY may go high for other reasons,
 | 
			
		||||
  //   and we only want to write data when finishing up.
 | 
			
		||||
  flopenr #(1) prevhreadyRamreg(HCLK,~HRESETn, 1'b1, HREADYRam,prevHREADYRam);
 | 
			
		||||
  assign risingHREADYRam = HREADYRam & ~prevHREADYRam;
 | 
			
		||||
 | 
			
		||||
  always @(posedge HCLK)
 | 
			
		||||
    HWADDR <= #1 A;
 | 
			
		||||
 | 
			
		||||
  bram2p1r1w #(`XLEN/8, 8, ADDR_WDITH, `FPGA)
 | 
			
		||||
  memory(.clk(HCLK), .enaA(1'b1),
 | 
			
		||||
		 .addrA(A[ADDR_WDITH+OFFSET-1:OFFSET]), .doutA(HREADRam),
 | 
			
		||||
		 .enaB(memwrite & risingHREADYRam), .weB(ByteMaskM),
 | 
			
		||||
		 .addrB(HWADDR[ADDR_WDITH+OFFSET-1:OFFSET]), .dinB(HWDATA));
 | 
			
		||||
		 
 | 
			
		||||
  
 | 
			
		||||
endmodule
 | 
			
		||||
  
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user