Modelsim basic sim

This commit is contained in:
felsabbagh3 2019-10-26 00:34:57 -04:00
parent 9110e8367e
commit 1181af1df2
25 changed files with 72 additions and 501 deletions

View file

@ -1,5 +1,5 @@
`include "VX_define.v"
// `include "VX_define.v"
module VX_alu(
input wire[31:0] in_1,

View file

@ -1,5 +1,5 @@
`include "VX_define.v"
// `include "VX_define.v"
module VX_decode(
// Fetch Inputs

View file

@ -1,5 +1,5 @@
`include "VX_define.v"
// `include "VX_define.v"
module VX_dmem_controller (
input wire clk,

View file

@ -1,3 +1,5 @@
`include "VX_define.v"
module VX_execute_unit (
// input wire clk,
// Input

View file

@ -1,3 +1,5 @@
`include "VX_define.v"
module VX_gpgpu_inst (
// Input
VX_gpu_inst_req_inter VX_gpu_inst_req,

View file

@ -1,3 +1,5 @@
`include "VX_define.v"
module VX_inst_multiplex (
// Inputs
VX_frE_to_bckE_req_inter VX_bckE_req,

View file

@ -1,3 +1,5 @@
`include "VX_define.v"
module VX_lsu_addr_gen (
input wire[`NT_M1:0][31:0] base_address,
input wire[31:0] offset,

View file

@ -1,17 +0,0 @@
module VX_one_counter (
input wire[`NW-1:0] valids,
output reg[`NW_M1:0] ones_found
);
integer i;
always @(*) begin
ones_found = 0;
for (i = `NW-1; i >= 0; i = i - 1) begin
if (valids[i]) begin
ones_found = ones_found + 1;
end
end
end
endmodule

View file

@ -1,4 +1,4 @@
`include "VX_define.v"
module VX_priority_encoder (
input wire[`NW-1:0] valids,

View file

@ -1,22 +0,0 @@
module VX_rename (
input wire clk,
input wire[`NW_M1:0] warp_num,
input wire[4:0] rs1,
input wire[4:0] rs2,
input wire[4:0] rd,
output wire stall,
);
reg[31:0] rename[`NW-1:0];
assign stall = rename[warp_num][rs1] || rename[warp_num][rs2];
alwa
endmodule

View file

@ -201,7 +201,7 @@ module VX_warp_scheduler (
assign wstall_this_cycle = wstall && (wstall_warp_num == warp_to_schedule); // Maybe bug
genvar curr_b;
integer curr_b;
always @(*) begin
total_barrier_stall = 0;
for (curr_b = 0; curr_b < `NUM_BARRIERS; curr_b=curr_b+1)
@ -273,10 +273,11 @@ module VX_warp_scheduler (
// Valid counter
VX_one_counter valid_counter(
.valids(visible_active),
.ones_found(num_active)
);
assign num_active = $countones(visible_active);
// VX_one_counter valid_counter(
// .valids(visible_active),
// .ones_found()
// );
wire ebreak = (warp_active == 0);

View file

@ -16,13 +16,14 @@ module VX_writeback (
);
assign no_slot_mem = mem_wb && (exec_wb || csr_wb);
wire exec_wb = (VX_inst_exec_wb.wb != 0) && (|VX_inst_exec_wb.wb_valid);
wire mem_wb = (VX_mem_wb.wb != 0) && (|VX_mem_wb.wb_valid);
wire csr_wb = (VX_csr_wb.wb != 0) && (|VX_csr_wb.valid);
assign no_slot_mem = mem_wb && (exec_wb || csr_wb);
assign VX_writeback_inter.write_data = exec_wb ? VX_inst_exec_wb.alu_result :
csr_wb ? VX_csr_wb.csr_result :
mem_wb ? VX_mem_wb.loaded_data :

View file

@ -1,8 +1,15 @@
`include "VX_define.v"
`include "../VX_define.v"
module Vortex(
module Vortex
#(
parameter CACHE_SIZE = 4096, // Bytes
parameter CACHE_WAYS = 1,
parameter CACHE_BLOCK = 128, // Bytes
parameter CACHE_BANKS = 8
)
(
input wire clk,
input wire reset,
input wire[31:0] icache_response_instruction,
@ -14,15 +21,18 @@ module Vortex(
output reg [31:0] o_m_read_addr,
output reg [31:0] o_m_evict_addr,
output reg o_m_valid,
output reg [31:0] o_m_writedata[`NUMBER_BANKS - 1:0][`NUM_WORDS_PER_BLOCK-1:0],
output reg [31:0] o_m_writedata[NUMBER_BANKS - 1:0][NUM_WORDS_PER_BLOCK-1:0],
output reg o_m_read_or_write,
// Rsp
input wire [31:0] i_m_readdata[`NUMBER_BANKS - 1:0][`NUM_WORDS_PER_BLOCK-1:0],
input wire [31:0] i_m_readdata[NUMBER_BANKS - 1:0][NUM_WORDS_PER_BLOCK-1:0],
input wire i_m_ready,
output wire out_ebreak
);
localparam NUMBER_BANKS = 8;
localparam NUM_WORDS_PER_BLOCK = 4;
wire memory_delay;
wire gpr_stage_delay;
wire schedule_delay;
@ -49,9 +59,9 @@ assign VX_dram_req_rsp.i_m_ready = i_m_ready;
genvar curr_bank;
genvar curr_word;
for (curr_bank = 0; curr_bank < `NUMBER_BANKS; curr_bank = curr_bank + 1) begin
for (curr_bank = 0; curr_bank < NUMBER_BANKS; curr_bank = curr_bank + 1) begin
for (curr_word = 0; curr_word < `NUM_WORDS_PER_BLOCK; curr_word = curr_word + 1) begin
for (curr_word = 0; curr_word < NUM_WORDS_PER_BLOCK; curr_word = curr_word + 1) begin
assign o_m_writedata[curr_bank][curr_word] = VX_dram_req_rsp.o_m_writedata[curr_bank][curr_word];
assign VX_dram_req_rsp.i_m_readdata[curr_bank][curr_word] = i_m_readdata[curr_bank][curr_word];

View file

@ -172,7 +172,8 @@ module VX_Cache_Bank
.CACHE_SIZE(CACHE_SIZE),
.CACHE_WAYS(CACHE_WAYS),
.CACHE_BLOCK(CACHE_BLOCK),
.CACHE_BANKS(CACHE_BANKS)) data_structures(
.CACHE_BANKS(CACHE_BANKS),
.NUM_WORDS_PER_BLOCK(NUM_WORDS_PER_BLOCK)) data_structures(
.clk (clk),
// Inputs
.addr (actual_index),

View file

@ -1,196 +0,0 @@
// To Do: Change way_id_out to an internal register which holds when in between access and finished.
// Also add a bit about wheter the "Way ID" is valid / being held or if it is just default
// Also make sure all possible output states are transmitted back to the bank correctly
`include "VX_define.v"
module VX_Cache_Block_DM(clk,
rst,
// These next 4 are possible modes that the Set could be in, I am making them 4 different variables for indexing purposes
access, // First
find_evict,
write_from_mem,
idle,
// entry,
o_tag,
block_offset,
writedata,
//byte_en,
write,
fetched_writedata,
//word_en,
//way_id_in,
//way_id_out,
readdata,
//wb_addr,
hit,
eviction_wb,
eviction_tag,
evicted_data,
//modify,
miss
//valid_data
//read_miss
);
parameter cache_entry = 14;
parameter ways_per_set = 4;
parameter Number_Blocks = 32;
input wire clk, rst;
input wire access;
input wire find_evict;
input wire write_from_mem;
input wire idle;
//input wire [cache_entry-1:0] entry;
input wire [21:0] o_tag;
input wire [4:0] block_offset;
input wire [31:0] writedata;
//input wire [3:0] byte_en;
input wire write; // 0 == False
input wire [31:0][31:0] fetched_writedata;
//input wire [3:0] word_en;
//input wire read_miss;
//input wire [1:0] way_id_in;
//output reg [1:0] way_id_out;
//output reg [31:0] readdata;
output wire [31:0] readdata;
//output reg hit;
output wire hit;
output reg miss;
output wire eviction_wb;
output wire [21:0] eviction_tag;
output wire [31:0][31:0] evicted_data;
//reg [31:0] eviction_data;
//output wire [22:0] wb_addr;
//output wire modify, valid_data;
//wire [2:0] i_tag;
//wire dirty;
//wire [24-cache_entry:0] write_tag_data;
// Table for one set
//reg [2:0] counter; // Determines which to evict
reg valid;
reg [21:0] tag;
reg clean;
//reg [31:0] data[31:0];
reg [31:0] data[31:0];
integer j;
// WS AW BS
//reg[3:0][31:0] some_data[5:0]; // before variable name is width, after name is height
//wire blockNun;
//wire WordNumWIthinABlock;
//ddata[31:0] =some_data[blockNun][WordNumWIthinABlock]
assign eviction_wb = miss && clean != 1'b1 && valid == 1'b1;
assign eviction_tag = tag;
assign readdata = (access && !write && tag == o_tag && valid) ? data[0] : 32'b0; // Fix with actual data
assign hit = (access && !write && tag == o_tag && valid) ? 1'b1 : 1'b0;
//assign evicted_data = (eviction_wb ) ? data : 0;
genvar k;
for (k = 0; k < Number_Blocks; k = k + 1) begin
assign evicted_data[k] = (eviction_wb) ? data[k] : 32'b0;
//data[j] <= fetched_writedata[(j+1) * 32 - 1 -: 32];
end
//assign eviction_data = data[counter[1:0]];
//assign hit = valid_data && (o_tag == i_tag);
//assign modify = valid_data && (o_tag != i_tag) && dirty;
//assign miss = !valid_data || ((o_tag != i_tag) && !dirty);
//assign wb_addr = {i_tag, entry};
always @(posedge clk) begin
if (rst) begin
end
if (find_evict) begin
if (tag == o_tag && valid) begin
//readdata <= data;
// evicted_data <= data;
end
end else if (access) begin
// Hit in First Column
if (tag == o_tag && valid) begin
if (write == 1'b0) begin // if it is a read
if (clean == 1'b1 ) begin
//hit <= 1'b1;
//readdata <= data;
miss <= 1'b0;
end else begin
//hit <= 1'b0;
//readdata <= 32'b0;
miss <= 1'b1;
end
end else if (write == 1'b1) begin
//for (j = 0; j < Number_Blocks; j = j + 1) begin
//data[j] <= fetched_writedata[(j+1) * 32 - 1 -: 32];
//end
data[block_offset] <= writedata;
clean <= 1'b0;
//hit <= 1'b1;
end
end
// Miss
else begin
//way_id_out <= counter;
miss <= 1'b1;
if (write == 1'b0) begin // Read Miss
clean <= 1'b1;
//data <= 0; // FIX WITH ACTUAL MEMORY ACCESS
for (j = 0; j < Number_Blocks; j = j + 1) begin
data[j] <= 32'b0;
end
end else if (write == 1'b1) begin // Write Miss
clean <= 1'b1;
data[block_offset] <= writedata;
//for (j = 0; j < Number_Blocks; j = j + 1) begin
//data[j] <= fetched_writedata[(j+1) * 32 - 1 -: 32];
//end
end
end
end
if (write_from_mem) begin
tag <= o_tag;
valid <= 1'b1;
//hit <= 1'b1;
if (write == 1'b0) begin // Read Miss
clean <= 1'b1;
//data <= 0; // FIX WITH ACTUAL MEMORY ACCESS
for (j = 0; j < Number_Blocks; j = j + 1) begin
data[j] <= 32'b0;
end
end else if (write == 1'b1) begin // Write Miss
clean <= 1'b0;
//data <= fetched_writedata;
for (j = 0; j < Number_Blocks; j = j + 1) begin
//data[j] <= fetched_writedata[(j+1) * 32 - 1 -: 32];
data[j] <= fetched_writedata[j];
end
end
end
if (idle) begin // Set "way" register equal to invalid value
//hit <= 1'b1; // set to know it is ready
miss <= 1'b0;
//readdata <= 32'hFFFFFFFF;
end
if (find_evict) begin // Keep "way" value the same !!!! Fix. Need to send back data with matching tag. Also need to ensure evicted data doesnt get lost
if (tag == o_tag && valid) begin
//readdata <= data;
end
//hit <= 1'b1;
miss <= 1'b0;
end
//eviction_data <= data;
end
endmodule

View file

@ -10,13 +10,15 @@ module VX_cache_bank_valid
output reg [NUMBER_BANKS - 1 : 0][`NT_M1:0] thread_track_banks
);
genvar t_id;
always @(*) begin
thread_track_banks = 0;
for (t_id = 0; t_id <= `NT_M1; t_id = t_id + 1)
begin
thread_track_banks[i_p_addr[t_id][4:2]][t_id] = i_p_valid[t_id];
end
end
generate
integer t_id;
always @(*) begin
thread_track_banks = 0;
for (t_id = 0; t_id <= `NT_M1; t_id = t_id + 1)
begin
thread_track_banks[i_p_addr[t_id][4:2]][t_id] = i_p_valid[t_id];
end
end
endgenerate
endmodule

View file

@ -4,10 +4,11 @@
module VX_cache_data
#(
parameter CACHE_SIZE = 4096, // Bytes
parameter CACHE_WAYS = 1,
parameter CACHE_BLOCK = 128, // Bytes
parameter CACHE_BANKS = 8
parameter CACHE_SIZE = 4096, // Bytes
parameter CACHE_WAYS = 1,
parameter CACHE_BLOCK = 128, // Bytes
parameter CACHE_BANKS = 8,
parameter NUM_WORDS_PER_BLOCK = 4
)
(
input wire clk, // Clock
@ -31,7 +32,7 @@ module VX_cache_data
localparam NUMBER_BANKS = CACHE_BANKS;
localparam CACHE_BLOCK_PER_BANK = (CACHE_BLOCK / CACHE_BANKS);
localparam NUM_WORDS_PER_BLOCK = CACHE_BLOCK / (CACHE_BANKS*4);
// localparam NUM_WORDS_PER_BLOCK = CACHE_BLOCK / (CACHE_BANKS*4);
localparam NUMBER_INDEXES = `NUM_IND;
wire currently_writing = (|we);
@ -56,12 +57,11 @@ module VX_cache_data
assign dirty_use = dirty[addr];
genvar f;
genvar z;
always @(posedge clk) begin : dirty_update
if (update_dirty) dirty[addr] <= dirt_new; // WRite Port
end
integer f;
always @(posedge clk) begin : data_update
for (f = 0; f < NUM_WORDS_PER_BLOCK; f = f + 1) begin
if (we[f][0]) data[addr][f][0] <= data_write[f][7 :0 ];

201
rtl/cache/bank.v vendored
View file

@ -1,201 +0,0 @@
`include "VX_define.v"
//`include "cache_set.v"
`include "VX_Cache_Block_DM.v"
module bank(clk,
rst,
state,
read_or_write,
//index,
//tag,
addr,
writedata,
fetched_write_data,
valid,
readdata,
miss_cache,
w2m_needed,
w2m_addr,
e_data,
//w2m_data,
ready
);
//parameter NUMBER_INDEXES = 16;
parameter NUMBER_INDEXES = 64;
localparam CACHE_IDLE = 0; // Idle
localparam SORT_BY_BANK = 1; // Determines the bank each thread will access
localparam CACHE_ACCESS = 2; // Accesses the bank and checks if it is a hit or miss
localparam FETCH_FROM_MEM = 3; // Send a request to mem looking for read data
localparam FETCH2 = 4; // Stall until memory gets back with the data
localparam UPDATE_CACHE = 5; // Update the cache with the data read from mem
localparam DIRTY_EVICT_GRAB_BLOCK = 6; // Grab the full block of dirty data
localparam DIRTY_EVICT_WB = 7; // Write back this block into memory
localparam WB_FROM_MEM = 8; // Currently unused
input wire clk, rst;
input wire read_or_write;
input wire [31:0] writedata;
input wire [31:0][31:0] fetched_write_data;
input wire [3:0] state;
//input wire [1:0] tag;
//input wire [3:0] index;
input wire [31:0] addr;
input wire valid;
output wire[NUMBER_INDEXES-1:0] [31:0] readdata;
output wire ready;
//output wire miss_cache;
output reg miss_cache;
output wire [31:0][31:0] e_data;
output wire w2m_needed;
//output reg [31:0] w2m_data;
output reg [31:0] w2m_addr;
wire [NUMBER_INDEXES-1:0] miss;
//wire [15:0][31:0] e_data;
wire [NUMBER_INDEXES-1:0] e_wb;
wire [NUMBER_INDEXES-1:0][21:0] e_tag;
//wire [3:0] index;
//wire valid_in_set;
//wire read_miss;
//wire modify;
wire hit;
reg [NUMBER_INDEXES-1:0] set_to_access;
reg [NUMBER_INDEXES-1:0] set_find_evict;
reg [NUMBER_INDEXES-1:0] set_idle;
reg [NUMBER_INDEXES-1:0] set_wfm;
//reg [1:0][15:0] way_id_recieved;
//reg [1:0][15:0] way_id_sending;
//reg wb_addr; // Concatination of tag and index for which we will write the data after a memory fetch
// Do logic about processing before going into the cache set here
assign miss_cache = (miss != 0);
assign ready = hit && (miss == 0);
//assign set_wfm =
//assign e_tag = miss ?
//always @(state) begin
//miss_cache = (miss != 0);
//end
//always @(state) begin
//for (indeces = 0; indeces < NUMBER_INDEXES; indeces = indeces + 1) begin
//if (set_to_access == indeces) begin
//if ({28'b0,addr[11:8]} == indeces && state == UPDATE_CACHE && valid) begin
// reset
//set_wfm[indeces] = 1'b1;
//set_find_evict[indeces] = 1'b0;
//set_idle[indeces] = 1'b0;
//set_to_access[indeces] = 1'b0;
//end else if ({28'b0,addr[11:8]} == indeces && state == CACHE_ACCESS && valid) begin
//set_to_access[indeces] = 1'b1;
//set_wfm[indeces] = 1'b0;
//set_idle[indeces] = 1'b0;
//set_find_evict[indeces] = 1'b0;
//end else if ({28'b0,addr[11:8]} == indeces && state == DIRTY_EVICT_GRAB_BLOCK && valid) begin
//set_to_access[indeces] = 1'b0;
//set_wfm[indeces] = 1'b0;
//set_idle[indeces] = 1'b0;
//set_find_evict[indeces] = 1'b1;
//end else begin
//set_find_evict[indeces] = 1'b0;
//set_to_access[indeces] = 1'b0;
//set_idle[indeces] = 1'b1;
//set_wfm[indeces] = 1'b0;
//end
//end
//end
for (indeces = 0; indeces < NUMBER_INDEXES; indeces = indeces + 1) begin
assign set_to_access[indeces] = ({28'b0,addr[11:8]} == indeces && state == CACHE_ACCESS && valid) ? 1'b1 : 1'b0;
assign set_find_evict[indeces] = ({28'b0,addr[11:8]} == indeces && state == DIRTY_EVICT_GRAB_BLOCK && valid) ? 1'b1 : 1'b0;
assign set_wfm[indeces] = ({28'b0,addr[11:8]} == indeces && state == UPDATE_CACHE && valid) ? 1'b1 : 1'b0;
assign set_idle[indeces] = (!set_to_access[indeces] && !set_wfm[indeces] && !set_find_evict[indeces]) ? 1'b1 : 1'b0;
end
// reg[31:0][31:0] data[NUMBER_INDEXES-1:0];
wire[$clog2(NUMBER_INDEXES)-1:0] actual_index;
assign actual_index = addr[11:8];
genvar indeces;
generate
for (indeces = 0; indeces < NUMBER_INDEXES; indeces = indeces + 1)
begin
VX_Cache_Block_DM set(
.clk (clk),
.rst (rst),
.actual_index (actual_index)
.access (set_to_access[indeces]),
.find_evict (set_find_evict[indeces]),
.write_from_mem (set_wfm[indeces]),
.idle (set_idle[indeces]),
//.entry,
//.o_tag (tag),
.o_tag (addr[31:10]),
.block_offset (addr[9:5]),
.writedata (writedata),
//byte_en,
.write (read_or_write),
.fetched_writedata (fetched_write_data),
//.way_id_in (way_id_sending[indeces]),
//.way_id_out (way_id_recieved[indeces]),
//word_en,
.readdata (readdata[indeces]),
//.wb_addr,
.hit (hit),
//.modify (modify),
.eviction_wb (e_wb[indeces]),
.eviction_tag (e_tag[indeces]),
//.evicted_data (e_data[indeces]),
.evicted_data (e_data),
.miss (miss[indeces])
//.valid_data (valid_in_set)
//.read_miss (read_miss)
);
end
endgenerate
//always @(e_wb) begin
// for (indeces = 0; indeces < NUMBER_INDEXES; indeces = indeces + 1) begin
// //if (set_to_access == indeces) begin
// if (e_wb[indeces] == 1'b1) begin
// // reset
// w2m_needed = 1'b1;
// w2m_addr = {e_tag[indeces], addr[11:0]}; // FIXME !!! Need to figure out how to do this (reassemble the address)
// //w2m_data = e_data[indeces];
// end
// end
//end
wire[$clog2(NUMBER_INDEXES)-1:0] index_w2m_addr;
wire found_w2m_addr;
VX_generic_pe #(.N(NUMBER_INDEXES)) find_evicted(
.valids(e_wb),
.index(index_w2m_addr),
.found (found_w2m_addr)
);
assign w2m_addr = {e_tag[index_w2m_addr], addr[9:0]};
assign w2m_needed = (e_wb != 0) ? 1'b1 : 1'b0;
for (indeces = 0; indeces < NUMBER_INDEXES; indeces = indeces + 1) begin
assign set_to_access[indeces] = ({28'b0,addr[11:8]} == indeces && state == CACHE_ACCESS && valid) ? 1'b1 : 1'b0;
end
// Do logic about processing done after going into the cache set here
endmodule

View file

@ -2,7 +2,7 @@
// Also add a bit about wheter the "Way ID" is valid / being held or if it is just default
// Also make sure all possible output states are transmitted back to the bank correctly
`include "VX_define.v"
// `include "VX_define.v"
module cache_set(clk,
rst,
// These next 4 are possible modes that the Set could be in, I am making them 4 different variables for indexing purposes

View file

@ -28,7 +28,7 @@ module vortex_tb (
initial begin
while (!ebreak) begin
while (!out_ebreak) begin
icache_response_instruction = 0;
end

View file

@ -1,6 +1,6 @@
`include "VX_define.v"
`include "../VX_define.v"
module VX_d_e_reg (
input wire clk,

View file

@ -1,4 +1,4 @@
`include "VX_define.v"
`include "../VX_define.v"
module VX_f_d_reg (
input wire clk,

View file

@ -72,7 +72,7 @@ module VX_priority_encoder_sm
end
reg[`NT_M1:0] serviced;
genvar curr_b;
integer curr_b;
always @(*) begin
serviced = 0;
for (curr_b = 0; curr_b <= NB; curr_b=curr_b+1) begin

View file

@ -1,21 +0,0 @@
`include "../VX_define.v"
module VX_set_bit (
input wire[1:0] index,
output reg[`NT_M1:0] mask
);
integer some_index;
always @(*) begin
for (some_index = 0; some_index <= `NT_M1; some_index = some_index + 1) begin
if (some_index[1:0] == index) begin
assign mask[some_index] = 0;
end
else begin
assign mask[some_index] = 1;
end
end
end
endmodule

View file

@ -39,13 +39,15 @@ reg shm_write;
wire [`NT_M1:0] orig_in_valid;
genvar i;
for(i = 0; i <= `NT_M1; i = i+1) begin
assign orig_in_valid[i] = in_valid[i];
end
genvar f;
generate
for(f = 0; f < `NT; f = f+1) begin
assign orig_in_valid[f] = in_valid[f];
end
assign out_valid = send_data ? temp_out_valid : 0;
assign out_data = send_data ? temp_out_data : 0;
assign out_valid = send_data ? temp_out_valid : 0;
assign out_data = send_data ? temp_out_data : 0;
endgenerate
VX_priority_encoder_sm #(.NB(NB), .BITS_PER_BANK(BITS_PER_BANK)) vx_priority_encoder_sm(
@ -65,6 +67,7 @@ VX_priority_encoder_sm #(.NB(NB), .BITS_PER_BANK(BITS_PER_BANK)) vx_priority_enc
);
genvar j;
integer i;
generate
for(j=0; j<= NB; j=j+1) begin
VX_shared_memory_block vx_shared_memory_block(
@ -76,7 +79,6 @@ for(j=0; j<= NB; j=j+1) begin
.data_out(block_rdata[j])
);
end
endgenerate
always @(*) begin
@ -132,4 +134,7 @@ always @(*) begin
end
end
endgenerate
endmodule