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

Subversion Repositories embedded_risc

[/] [embedded_risc/] [trunk/] [Verilog/] [lru_instruction_cache.v] - Rev 27

Compare with Previous | Blame | View Log

/**********************************************************
 MODULE:		Sub Level Least Recently Used Instruction Cache
 
 FILE NAME:	lru_instruction_cache.v
 VERSION:	1.0
 DATE:		May 7th, 2002
 AUTHOR:		Hossein Amidi
 COMPANY:	
 CODE TYPE:	Register Transfer Level
 
 DESCRIPTION:	This module is the top level RTL code of LRU
 instruction Cache verilog code.
 
 It will instantiate the following blocks in the ASIC:
 
 1)	Instruction Cache Way 0
 2)	Instruction Cache Way 1
 3)	Instruction Cache Way 2
 4)	Instruction Cache Way 3
 
 
 Hossein Amidi
 (C) April 2002
 
*********************************************************/
 
// DEFINES
`timescale 1ns / 10ps
 
// TOP MODULE
module lru_instruction_cache(// Inputs
						reset,
						clk0,
						cache_host_addr,
						cache_host_cmd,
						cache_request,
						cache_host_datain,
						cache_bus_grant,
						cache_datain,
						// Outputs
						cache_host_dataout,
						cache_hit,
						cache_miss,
						cache_bus_request,
						cache_addr,
						cache_cmd,
						cache_dataout
						);
 
 
// Parameter
`include        "parameter.v"
 
// Inputs
input reset;
input clk0;
input [padd_size - 1 : 0]cache_host_addr;
input [cmd_size  - 1 : 0]cache_host_cmd;
input cache_request;
input [data_size - 1 : 0]cache_host_datain;
input cache_bus_grant;
input [data_size - 1 : 0]cache_datain;
 
// Outputs
output [data_size - 1 : 0]cache_host_dataout;
output cache_hit;
output cache_miss;
output cache_bus_request;
output [padd_size - 1 : 0]cache_addr;
output [cmd_size  - 1 : 0]cache_cmd;
output [data_size - 1 : 0]cache_dataout;
 
// Signal Declarations
wire reset;
wire clk0;
wire [padd_size - 1 : 0]cache_host_addr;
wire [cmd_size  - 1 : 0]cache_host_cmd;
wire cache_request;
wire [data_size - 1 : 0]cache_host_datain;
wire cache_bus_grant;
wire [data_size - 1 : 0]cache_datain;
 
reg [data_size - 1 : 0]cache_host_dataout;
reg cache_hit;
reg cache_miss;
wire cache_bus_request;
reg [padd_size - 1 : 0]cache_addr;
reg [cmd_size  - 1 : 0]cache_cmd;
reg [data_size - 1 : 0]cache_dataout;
 
wire [cache_line_size - 1 : 0]instruction_cache_datain_way0;
wire [cache_line_size - 1 : 0]instruction_cache_datain_way1;
wire [cache_line_size - 1 : 0]instruction_cache_datain_way2;
wire [cache_line_size - 1 : 0]instruction_cache_datain_way3;
wire [cache_line_size - 1 : 0]instruction_cache_dataout_way0;
wire [cache_line_size - 1 : 0]instruction_cache_dataout_way1;
wire [cache_line_size - 1 : 0]instruction_cache_dataout_way2;
wire [cache_line_size - 1 : 0]instruction_cache_dataout_way3;
 
wire cache_wr;
reg  [cache_valid - 1 : 0]valid0;
reg  [cache_valid - 1 : 0]valid1;
reg  [cache_valid - 1 : 0]valid2;
reg  [cache_valid - 1 : 0]valid3;
wire [cache_tag - 1 : 0]tag;
wire [cache_tag - 1 : 0]read_tag0;
wire [cache_tag - 1 : 0]read_tag1;
wire [cache_tag - 1 : 0]read_tag2;
wire [cache_tag - 1 : 0]read_tag3;
 
wire [cache_valid - 1 : 0]wvalid0;
wire [cache_valid - 1 : 0]wvalid1;
wire [cache_valid - 1 : 0]wvalid2;
wire [cache_valid - 1 : 0]wvalid3;
 
 
/********* Internal Register of Instruction cache configuration *********/
reg [cache_reg_width - 1 : 0] cache_register [cache_reg_depth - 1 : 0];
 
 
 
// Assignment statments
assign cache_bus_request = cache_miss;
assign cache_wr = (cache_host_cmd == 010) ? 1'b1 : 1'b0;
 
assign tag = cache_host_addr[23:5];
assign read_tag0 = instruction_cache_dataout_way0[50:32];
assign read_tag1 = instruction_cache_dataout_way1[50:32];
assign read_tag2 = instruction_cache_dataout_way2[50:32];
assign read_tag3 = instruction_cache_dataout_way3[50:32];
assign instruction_cache_datain_way0 = ({wvalid0,tag,cache_datain});
assign instruction_cache_datain_way1 = ({wvalid1,tag,cache_datain});
assign instruction_cache_datain_way2 = ({wvalid2,tag,cache_datain});
assign instruction_cache_datain_way3 = ({wvalid3,tag,cache_datain});
 
assign wvalid0 = valid0;
assign wvalid1 = valid1;
assign wvalid2 = valid2;
assign wvalid3 = valid3;
 
/********************************** Sub Level Instantiation *********************************/
 
 
instruction_cache_way0 instruction_cache_way0_0 (// Input
																.A(cache_host_addr[4:0]),
																.CLK(clk0),
																.D(instruction_cache_datain_way0),
																.WE(cache_wr),
																.SPO(instruction_cache_dataout_way0));
 
 
instruction_cache_way1 instruction_cache_way1_0 (// Input
																.A(cache_host_addr[4:0]),
																.CLK(clk0),
																.D(instruction_cache_datain_way1),
																.WE(cache_wr),
																.SPO(instruction_cache_dataout_way1));
 
 
instruction_cache_way2 instruction_cache_way2_0 (// Input
																.A(cache_host_addr[4:0]),
																.CLK(clk0),
																.D(instruction_cache_datain_way2),
																.WE(cache_wr),
																.SPO(instruction_cache_dataout_way2));
 
 
instruction_cache_way3 instruction_cache_way3_0 (// Input
																.A(cache_host_addr[4:0]),
																.CLK(clk0),
																.D(instruction_cache_datain_way3),
																.WE(cache_wr),
																.SPO(instruction_cache_dataout_way3));
 
 
 
// Generate the LRU talbe
always @(posedge reset or posedge clk0)
begin
	if(reset == 1'b1)
	begin
		valid0 <= 2'b00;
		valid1 <= 2'b00;
		valid2 <= 2'b10;
		valid3 <= 2'b10;
	end
	else
	begin
		if((cache_wr == 1'b1) && (wvalid0 == 2'b00))
			valid0 <= 2'b01;
		else
		if((cache_wr == 1'b1) && (wvalid0 == 2'b01))
			valid0 <= 2'b00;
		else
		if((cache_wr == 1'b1) && (wvalid1 == 2'b00))
			valid1 <= 2'b01;
		else
		if((cache_wr == 1'b1) && (wvalid1 == 2'b01))
			valid1 <= 2'b00;
		else
		if((cache_wr == 1'b1) && (wvalid2 == 2'b10))
			valid2 <= 2'b11;
		else
		if((cache_wr == 1'b1) && (wvalid2 == 2'b11))
			valid2 <= 2'b10;
		else
		if((cache_wr == 1'b1) && (wvalid3 == 2'b10))
			valid3 <= 2'b11;
		else
		if((cache_wr == 1'b1) && (wvalid3 == 2'b11))
			valid3 <= 2'b10;
	end
end
 
 
// Check for cache way validity, if matches generate the cache hit signal
// else generate cache miss signal
always @(posedge reset or posedge clk0)
begin
	if(reset == 1'b1)
		cache_dataout <= 32'h0;
	else
	if((cache_request == 1'b1) && (cache_host_cmd == 001) && (read_tag0 == cache_host_addr[23:5]))
	begin
		cache_hit <= 1'b1;
		cache_dataout <= instruction_cache_dataout_way0[31:0];
	end
	else
	if((cache_request == 1'b1) && (cache_host_cmd == 001) && (read_tag1 == cache_host_addr[23:5]))
	begin
		cache_hit <= 1'b1;
		cache_dataout <= instruction_cache_dataout_way1[31:0];
	end
	else
	if((cache_request == 1'b1) && (cache_host_cmd == 001) && (read_tag2 == cache_host_addr[23:5]))
	begin
		cache_hit <= 1'b1;
		cache_dataout <= instruction_cache_dataout_way2[31:0];
	end
	else
	if((cache_request == 1'b1) && (cache_host_cmd == 001) && (read_tag3 == cache_host_addr[23:5]))
	begin
		cache_hit <= 1'b1;
		cache_dataout <= instruction_cache_dataout_way3[31:0];
	end
	else
	if((cache_request == 1'b1) && (cache_host_cmd == 001))
	begin
		cache_miss <= 1'b1;
		cache_hit  <= 1'b0;
		cache_dataout <= 32'h0;
	end
	else
	begin
		cache_miss <= 1'b0;
		cache_hit  <= 1'b0;
		cache_dataout <= 32'h0;
	end
end
 
 
// Access to internal register by CPU address and command signals (write/read)
always @(posedge reset or posedge clk0)
begin
	if(reset == 1'b1)
	begin
		cache_host_dataout <= 32'h0;
		cache_register[0] <= 32'h0;
		cache_register[1] <= 32'h0;
		cache_register[2] <= 32'h0;
		cache_register[3] <= 32'h0;
		cache_register[4] <= 32'h0;
		cache_register[5] <= 32'h0;
		cache_register[6] <= 32'h0;
		cache_register[7] <= 32'h0;
	end
	else
	begin
		if(cache_host_cmd == 3'b010)	// Write from Host to Cache internal Registers
		begin
			case (cache_host_addr)
 
				24'h080018:	cache_register[0] <= cache_host_datain;	// Status Register
				24'h080019:	cache_register[1] <= cache_host_datain;	// Read Master Start Address
				24'h08001A:	cache_register[2] <= cache_host_datain;	// Write Master Start Address
				24'h08001B:	cache_register[3] <= cache_host_datain;	// Length in Bytes
				24'h08001C:	cache_register[4] <= cache_host_datain;	// Reserved
				24'h08001D:	cache_register[5] <= cache_host_datain; 	// Reserved
				24'h08001E:	cache_register[6] <= cache_host_datain;	// Control
				24'h08001F:	cache_register[7] <= cache_host_datain; 	// Reserved
			endcase
		end
		else
		if(cache_host_cmd == 3'b001)	// Read from Cache internal Registers to Host
		begin
			case (cache_host_addr)
 
				24'h080018:	cache_host_dataout <= cache_register[0];
				24'h080019:	cache_host_dataout <= cache_register[1];
				24'h08001A:	cache_host_dataout <= cache_register[2];
				24'h08001B:	cache_host_dataout <= cache_register[3];
				24'h08001C:	cache_host_dataout <= cache_register[4];
				24'h08001D:	cache_host_dataout <= cache_register[5];
				24'h08001E:	cache_host_dataout <= cache_register[6];
				24'h08001F:	cache_host_dataout <= cache_register[7];
			endcase
		end
	end	
end
 
 
always @(posedge reset or posedge clk0)
begin
	if(reset == 1'b1)
	begin
		cache_addr <= 24'h0;
		cache_cmd <= 3'h0;
	end
	else
	begin
		cache_addr <= cache_bus_grant & cache_host_addr;
		cache_cmd <= cache_bus_grant & cache_host_cmd;
	end
end
 
endmodule
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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