Skip to content

Commit 3f09859

Browse files
committedJun 10, 2012
Add a draft of ITLB to Milkymist MMU
1 parent 188ce66 commit 3f09859

File tree

3 files changed

+380
-10
lines changed

3 files changed

+380
-10
lines changed
 

Diff for: ‎lm32_cpu.v

+10-2
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,8 @@ wire mc_stall_request_x; // Multi-cycle arithmetic unit s
616616
wire [`LM32_WORD_RNG] mc_result_x;
617617
`endif
618618

619-
wire [`LM32_WORD_RNG] load_store_csr_read_data_x;// Data read from load store CSRs
619+
wire [`LM32_WORD_RNG] load_store_csr_read_data_x;// Data read from load store unit CSRs
620+
wire [`LM32_WORD_RNG] instruction_csr_read_data_x;// Data read from instruction unit CSRs
620621
// From CSRs
621622
`ifdef CFG_INTERRUPTS_ENABLED
622623
wire [`LM32_WORD_RNG] interrupt_csr_read_data_x;// Data read from interrupt CSRs
@@ -819,6 +820,7 @@ lm32_instruction_unit #(
819820
.branch_target_x (branch_target_x),
820821
`endif
821822
.exception_m (exception_m),
823+
.exception_x (exception_x),
822824
.branch_taken_m (branch_taken_m),
823825
.branch_mispredict_taken_m (branch_mispredict_taken_m),
824826
.branch_target_m (branch_target_m),
@@ -834,7 +836,11 @@ lm32_instruction_unit #(
834836
.dcache_restart_request (dcache_restart_request),
835837
.dcache_refill_request (dcache_refill_request),
836838
.dcache_refilling (dcache_refilling),
837-
`endif
839+
`endif
840+
.csr (csr_x),
841+
.csr_write_data (operand_1_x),
842+
.csr_write_enable (csr_write_enable_q_x),
843+
.eret_q_x (eret_q_x),
838844
`ifdef CFG_IWB_ENABLED
839845
// From Wishbone
840846
.i_dat_i (I_DAT_I),
@@ -863,6 +869,8 @@ lm32_instruction_unit #(
863869
`ifdef CFG_IROM_ENABLED
864870
.irom_data_m (irom_data_m),
865871
`endif
872+
.itlb_miss (itlb_miss_exception),
873+
.csr_read_data (instruction_csr_read_data_x),
866874
`ifdef CFG_IWB_ENABLED
867875
// To Wishbone
868876
.i_dat_o (I_DAT_O),

Diff for: ‎lm32_icache.v

+331-4
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@
5757
`include "lm32_include.v"
5858

5959
`ifdef CFG_ICACHE_ENABLED
60+
`define LM32_KERNEL_MODE 1
61+
`define LM32_USER_MODE 0
6062

6163
`define LM32_IC_ADDR_OFFSET_RNG addr_offset_msb:addr_offset_lsb
6264
`define LM32_IC_ADDR_SET_RNG addr_set_msb:addr_set_lsb
@@ -79,6 +81,15 @@
7981
`define LM32_IC_STATE_CHECK 4'b0100
8082
`define LM32_IC_STATE_REFILL 4'b1000
8183

84+
`define LM32_ITLB_CTRL_FLUSH 5'h1
85+
`define LM32_ITLB_CTRL_UPDATE 5'h2
86+
`define LM32_TLB_CTRL_SWITCH_TO_KERNEL_MODE 5'h4
87+
`define LM32_TLB_CTRL_SWITCH_TO_USER_MODE 5'h8
88+
`define LM32_TLB_CTRL_INVALIDATE_ENTRY 5'h10
89+
90+
`define LM32_TLB_STATE_CHECK 2'b01
91+
`define LM32_TLB_STATE_FLUSH 2'b10
92+
8293
/////////////////////////////////////////////////////
8394
// Module interface
8495
/////////////////////////////////////////////////////
@@ -100,13 +111,24 @@ module lm32_icache (
100111
`endif
101112
valid_d,
102113
branch_predict_taken_d,
114+
csr,
115+
csr_write_data,
116+
csr_write_enable,
117+
exception_x,
118+
eret_q_x,
119+
exception_m,
103120
// ----- Outputs -----
104121
stall_request,
105122
restart_request,
106123
refill_request,
107124
refill_address,
125+
physical_refill_address,
108126
refilling,
109-
inst
127+
inst,
128+
itlb_miss_int,
129+
kernel_mode,
130+
pa,
131+
csr_read_data
110132
);
111133

112134
/////////////////////////////////////////////////////
@@ -119,6 +141,39 @@ parameter bytes_per_line = 16; // Number of bytes per c
119141
parameter base_address = 0; // Base address of cachable memory
120142
parameter limit = 0; // Limit (highest address) of cachable memory
121143

144+
parameter itlb_sets = 1024; // Number of lines of ITLB
145+
parameter page_size = 4096; // System page size
146+
147+
`define LM32_ITLB_IDX_RNG addr_itlb_index_msb:addr_itlb_index_lsb
148+
`define LM32_ITLB_ADDRESS_PFN_RNG addr_pfn_msb:addr_pfn_lsb
149+
`define LM32_PAGE_OFFSET_RNG addr_page_offset_msb:addr_page_offset_lsb
150+
`define LM32_ITLB_INVALID_ADDRESS { vpfn_width{1'b1} }
151+
152+
localparam addr_page_offset_lsb = 0;
153+
localparam addr_page_offset_msb = addr_page_offset_lsb + clogb2(page_size) - 2;
154+
localparam addr_itlb_index_width = clogb2(itlb_sets) - 1;
155+
localparam addr_itlb_index_lsb = addr_page_offset_msb + 1;
156+
localparam addr_itlb_index_msb = addr_itlb_index_lsb + addr_itlb_index_width - 1;
157+
localparam addr_pfn_lsb = addr_page_offset_msb + 1;
158+
localparam addr_pfn_msb = `LM32_WORD_WIDTH - 1;
159+
localparam vpfn_width = `LM32_WORD_WIDTH - (clogb2(page_size) - 1);
160+
localparam addr_itlb_tag_width = vpfn_width - addr_itlb_index_width;
161+
localparam addr_itlb_tag_lsb = addr_itlb_index_msb + 1;
162+
localparam addr_itlb_tag_msb = addr_itlb_tag_lsb + addr_itlb_tag_width - 1;
163+
164+
`define LM32_ITLB_TAG_INVALID { addr_itlb_tag_width{ 1'b0 } }
165+
`define LM32_ITLB_LOOKUP_RANGE vpfn_width-1:0
166+
167+
/* The following define is the range containing the TAG inside the itlb_read_data wire which contains the ITLB value from BlockRAM
168+
* Indeed itlb_read_data contains { VALID_BIT, TAG_VALUE, LOOKUP_VALUE }
169+
* LM32_ITLB_TAG_RANGE is the range to extract the TAG_VALUE */
170+
`define LM32_ITLB_TAG_RANGE vpfn_width+addr_itlb_tag_width-1:vpfn_width
171+
172+
/* The following define is the range containing the TAG inside a memory address like itlb_update_vaddr_csr_reg for instance. */
173+
`define LM32_ITLB_ADDR_TAG_RNG addr_itlb_tag_msb:addr_itlb_tag_lsb
174+
`define LM32_ITLB_VALID_BIT vpfn_width+addr_itlb_tag_width
175+
176+
122177
localparam addr_offset_width = clogb2(bytes_per_line)-1-2;
123178
localparam addr_set_width = clogb2(sets)-1;
124179
localparam addr_offset_lsb = 2;
@@ -154,10 +209,20 @@ input iflush; // Flush the cache
154209
input select_f; // Instruction in F stage is mapped through instruction cache
155210
`endif
156211

212+
input [`LM32_CSR_RNG] csr; // CSR read/write index
213+
input [`LM32_WORD_RNG] csr_write_data; // Data to write to specified CSR
214+
input csr_write_enable; // CSR write enable
215+
input exception_x; // An exception occured in the X stage
216+
input exception_m;
217+
input eret_q_x;
218+
157219
/////////////////////////////////////////////////////
158220
// Outputs
159221
/////////////////////////////////////////////////////
160222

223+
output csr_read_data;
224+
wire [`LM32_WORD_RNG] csr_read_data;
225+
161226
output stall_request; // Request to stall the pipeline
162227
wire stall_request;
163228
output restart_request; // Request to restart instruction that caused the cache miss
@@ -166,11 +231,18 @@ output refill_request; // Request to refill a cache
166231
wire refill_request;
167232
output [`LM32_PC_RNG] refill_address; // Base address of cache refill
168233
reg [`LM32_PC_RNG] refill_address;
234+
output [`LM32_PC_RNG] physical_refill_address;
235+
reg [`LM32_PC_RNG] physical_refill_address;
169236
output refilling; // Indicates the instruction cache is currently refilling
170237
reg refilling;
171238
output [`LM32_INSTRUCTION_RNG] inst; // Instruction read from cache
172239
wire [`LM32_INSTRUCTION_RNG] inst;
173240

241+
output kernel_mode;
242+
wire kernel_mode;
243+
244+
output itlb_miss_int;
245+
174246
/////////////////////////////////////////////////////
175247
// Internal nets and registers
176248
/////////////////////////////////////////////////////
@@ -199,7 +271,41 @@ reg [`LM32_IC_ADDR_OFFSET_RNG] refill_offset;
199271
wire last_refill;
200272
reg [`LM32_IC_TMEM_ADDR_RNG] flush_set;
201273

202-
genvar i;
274+
wire [addr_itlb_index_width-1:0] itlb_data_read_address;
275+
wire [addr_itlb_index_width-1:0] itlb_data_write_address;
276+
wire itlb_data_read_port_enable;
277+
wire itlb_write_port_enable;
278+
wire [vpfn_width + addr_itlb_tag_width + 1 - 1:0] itlb_write_data; // +1 is for valid_bit
279+
wire [vpfn_width + addr_itlb_tag_width + 1 - 1:0] itlb_read_data; // +1 is for valid_bit
280+
281+
wire [`LM32_WORD_RNG] physical_address;
282+
283+
wire [`LM32_WORD_RNG] pa;
284+
output [`LM32_WORD_RNG] pa;
285+
286+
assign pa = physical_address;
287+
288+
reg kernel_mode_reg = `LM32_KERNEL_MODE;
289+
wire switch_to_kernel_mode;
290+
wire switch_to_user_mode;
291+
reg [`LM32_WORD_RNG] itlb_update_vaddr_csr_reg = `LM32_WORD_WIDTH'd0;
292+
reg [`LM32_WORD_RNG] itlb_update_paddr_csr_reg = `LM32_WORD_WIDTH'd0;
293+
reg [1:0] itlb_state = `LM32_TLB_STATE_CHECK;
294+
reg [`LM32_WORD_RNG] itlb_ctrl_csr_reg = `LM32_WORD_WIDTH'd0;
295+
reg itlb_updating;
296+
reg [addr_itlb_index_width-1:0] itlb_update_set;
297+
reg itlb_flushing;
298+
reg [addr_itlb_index_width-1:0] itlb_flush_set;
299+
wire itlb_miss;
300+
reg itlb_miss_q = `FALSE;
301+
wire itlb_miss_int;
302+
reg [`LM32_WORD_RNG] itlb_miss_addr;
303+
wire itlb_data_valid;
304+
wire [`LM32_ITLB_LOOKUP_RANGE] itlb_lookup;
305+
306+
genvar i, j;
307+
308+
assign kernel_mode = kernel_mode_reg;
203309

204310
/////////////////////////////////////////////////////
205311
// Functions
@@ -211,6 +317,39 @@ genvar i;
211317
// Instantiations
212318
/////////////////////////////////////////////////////
213319

320+
// ITLB instantiation
321+
lm32_ram
322+
#(
323+
// ----- Parameters -------
324+
.data_width (vpfn_width + addr_itlb_tag_width + 1),
325+
.address_width (addr_itlb_index_width)
326+
// Modified for Milkymist: removed non-portable RAM parameters
327+
) itlb_data_ram
328+
(
329+
// ----- Inputs -------
330+
.read_clk (clk_i),
331+
.write_clk (clk_i),
332+
.reset (rst_i),
333+
.read_address (itlb_data_read_address),
334+
.enable_read (itlb_data_read_port_enable),
335+
.write_address (itlb_data_write_address),
336+
.enable_write (`TRUE),
337+
.write_enable (itlb_write_port_enable),
338+
.write_data (itlb_write_data),
339+
// ----- Outputs -------
340+
.read_data (itlb_read_data)
341+
);
342+
343+
`ifdef CFG_VERBOSE_DISPLAY_ENABLED
344+
always @(posedge clk_i)
345+
begin
346+
if (itlb_write_port_enable)
347+
begin
348+
$display("[ITLB data : %d] Writing 0x%08X to 0x%08X", $time, itlb_write_data, itlb_data_write_address);
349+
end
350+
end
351+
`endif
352+
214353
generate
215354
for (i = 0; i < associativity; i = i + 1)
216355
begin : memories
@@ -268,11 +407,45 @@ endgenerate
268407
// Combinational logic
269408
/////////////////////////////////////////////////////
270409

410+
// CSR Write
411+
always @(posedge clk_i `CFG_RESET_SENSITIVITY)
412+
begin
413+
if (rst_i == `TRUE)
414+
begin
415+
itlb_ctrl_csr_reg <= `LM32_WORD_WIDTH'd0;
416+
itlb_update_vaddr_csr_reg <= `LM32_WORD_WIDTH'd0;
417+
itlb_update_paddr_csr_reg <= `LM32_WORD_WIDTH'd0;
418+
end
419+
else
420+
begin
421+
if (csr_write_enable)
422+
begin
423+
case (csr)
424+
`LM32_CSR_TLB_CTRL: if (~csr_write_data[0]) itlb_ctrl_csr_reg[31:1] <= csr_write_data[31:1];
425+
`LM32_CSR_TLB_VADDRESS: if (~csr_write_data[0]) itlb_update_vaddr_csr_reg[31:1] <= csr_write_data[31:1];
426+
`LM32_CSR_TLB_PADDRESS: if (~csr_write_data[0]) itlb_update_paddr_csr_reg[31:1] <= csr_write_data[31:1];
427+
endcase
428+
end
429+
itlb_ctrl_csr_reg[0] <= 0;
430+
itlb_update_vaddr_csr_reg[0] <= 0;
431+
itlb_update_paddr_csr_reg[0] <= 0;
432+
end
433+
end
434+
271435
// Compute which ways in the cache match the address address being read
272436
generate
273437
for (i = 0; i < associativity; i = i + 1)
274438
begin : match
275-
assign way_match[i] = ({way_tag[i], way_valid[i]} == {address_f[`LM32_IC_ADDR_TAG_RNG], `TRUE});
439+
440+
assign itlb_read_tag = itlb_read_data[`LM32_ITLB_TAG_RANGE];
441+
assign itlb_data_valid = itlb_read_data[`LM32_ITLB_VALID_BIT];
442+
assign itlb_lookup = itlb_read_data[`LM32_ITLB_LOOKUP_RANGE];
443+
444+
//assign way_match[i] = ({way_tag[i], way_valid[i]} == {address_f[`LM32_IC_ADDR_TAG_RNG], `TRUE});
445+
assign way_match[i] = (kernel_mode_reg == `LM32_KERNEL_MODE) ?
446+
({way_tag[i], way_valid[i]} == {address_f[`LM32_IC_ADDR_TAG_RNG], `TRUE}) :
447+
448+
({way_tag[i], way_valid[i]} == {itlb_lookup, `TRUE });
276449
end
277450
endgenerate
278451

@@ -304,6 +477,25 @@ assign tmem_write_address = flushing
304477
? flush_set
305478
: refill_address[`LM32_IC_ADDR_SET_RNG];
306479

480+
// Compute address to use to index into the ITLB data memory
481+
482+
assign itlb_data_read_address = address_a[`LM32_ITLB_IDX_RNG];
483+
484+
// tlb_update_address will receive data from a CSR register
485+
assign itlb_data_write_address = itlb_update_vaddr_csr_reg[`LM32_ITLB_IDX_RNG];
486+
487+
assign itlb_data_read_port_enable = (stall_a == `FALSE) || !stall_f;
488+
assign itlb_write_port_enable = itlb_updating || itlb_flushing;
489+
490+
assign physical_address = (kernel_mode_reg == `LM32_KERNEL_MODE)
491+
? {address_f, 2'b0}
492+
: {itlb_lookup, address_f[`LM32_PAGE_OFFSET_RNG+2], 2'b0};
493+
494+
assign itlb_write_data = (itlb_flushing == `TRUE)
495+
? {`FALSE, {addr_itlb_tag_width{1'b0}}, {vpfn_width{1'b0}}}
496+
: {`TRUE, {itlb_update_vaddr_csr_reg[`LM32_ITLB_ADDR_TAG_RNG]}, itlb_update_paddr_csr_reg[`LM32_ITLB_ADDRESS_PFN_RNG]};
497+
498+
307499
// Compute signal to indicate when we are on the last refill accesses
308500
generate
309501
if (bytes_per_line > 4)
@@ -330,7 +522,7 @@ endgenerate
330522

331523
// On the last refill cycle set the valid bit, for all other writes it should be cleared
332524
assign tmem_write_data[`LM32_IC_TAGS_VALID_RNG] = last_refill & !flushing;
333-
assign tmem_write_data[`LM32_IC_TAGS_TAG_RNG] = refill_address[`LM32_IC_ADDR_TAG_RNG];
525+
assign tmem_write_data[`LM32_IC_TAGS_TAG_RNG] = physical_refill_address[`LM32_IC_ADDR_TAG_RNG];
334526

335527
// Signals that indicate which state we are in
336528
assign flushing = |state[1:0];
@@ -414,11 +606,13 @@ begin
414606
restart_request <= `FALSE;
415607
if (iflush == `TRUE)
416608
begin
609+
physical_refill_address <= physical_address[`LM32_PC_RNG];
417610
refill_address <= address_f;
418611
state <= `LM32_IC_STATE_FLUSH;
419612
end
420613
else if (miss == `TRUE)
421614
begin
615+
physical_refill_address <= physical_address[`LM32_PC_RNG];
422616
refill_address <= address_f;
423617
state <= `LM32_IC_STATE_REFILL;
424618
end
@@ -441,6 +635,139 @@ begin
441635
end
442636
end
443637

638+
assign csr_read_data = itlb_miss_addr;
639+
640+
assign itlb_miss = (kernel_mode_reg == `LM32_USER_MODE) && (read_enable_f) && ~(itlb_data_valid);
641+
642+
always @(posedge clk_i `CFG_RESET_SENSITIVITY)
643+
begin
644+
if (rst_i == `TRUE)
645+
itlb_miss_q <= `FALSE;
646+
else
647+
begin
648+
if (itlb_miss && ~itlb_miss_q)
649+
itlb_miss_q <= `TRUE;
650+
else if (itlb_miss_q && exception_m)
651+
itlb_miss_q <= `FALSE;
652+
end
653+
end
654+
655+
assign itlb_miss_int = (itlb_miss || itlb_miss_q);
656+
657+
always @(posedge clk_i `CFG_RESET_SENSITIVITY)
658+
begin
659+
if (rst_i == `TRUE)
660+
begin
661+
itlb_flushing <= 1;
662+
itlb_flush_set <= {addr_itlb_index_width{1'b1}};
663+
itlb_state <= `LM32_TLB_STATE_FLUSH;
664+
itlb_updating <= 0;
665+
itlb_miss_addr <= `LM32_WORD_WIDTH'd0;
666+
end
667+
else
668+
begin
669+
case (itlb_state)
670+
671+
`LM32_TLB_STATE_CHECK:
672+
begin
673+
itlb_updating <= 0;
674+
itlb_flushing <= 0;
675+
if (itlb_miss == `TRUE)
676+
begin
677+
itlb_miss_addr <= address_f;
678+
$display("WARNING : ITLB MISS on addr 0x%08X at time %t", address_f, $time);
679+
end
680+
if (csr_write_enable && ~csr_write_data[0])
681+
begin
682+
// FIXME : test for kernel mode is removed for testing purposes ONLY
683+
if (csr == `LM32_CSR_TLB_CTRL /*&& (kernel_mode_reg == `LM32_KERNEL_MODE)*/)
684+
begin
685+
`ifdef CFG_VERBOSE_DISPLAY_ENABLED
686+
$display("ITLB WCSR at %t with csr_write_data == 0x%08X", $time, csr_write_data);
687+
`endif
688+
case (csr_write_data[5:1])
689+
`LM32_ITLB_CTRL_FLUSH:
690+
begin
691+
`ifdef CFG_VERBOSE_DISPLAY_ENABLED
692+
$display("it's a FLUSH at %t", $time);
693+
`endif
694+
itlb_flushing <= 1;
695+
itlb_flush_set <= {addr_itlb_index_width{1'b1}};
696+
itlb_state <= `LM32_TLB_STATE_FLUSH;
697+
itlb_updating <= 0;
698+
end
699+
700+
`LM32_ITLB_CTRL_UPDATE:
701+
begin
702+
`ifdef CFG_VERBOSE_DISPLAY_ENABLED
703+
$display("it's an UPDATE at %t", $time);
704+
`endif
705+
itlb_updating <= 1;
706+
end
707+
708+
`LM32_TLB_CTRL_INVALIDATE_ENTRY:
709+
begin
710+
`ifdef CFG_VERBOSE_DISPLAY_ENABLED
711+
$display("it's an INVALIDATE ENTRY at %t", $time);
712+
`endif
713+
itlb_flushing <= 1;
714+
itlb_flush_set <= itlb_update_vaddr_csr_reg[`LM32_ITLB_IDX_RNG];
715+
itlb_updating <= 0;
716+
itlb_state <= `LM32_TLB_STATE_CHECK;
717+
end
718+
719+
endcase
720+
end
721+
end
722+
end
723+
724+
`LM32_TLB_STATE_FLUSH:
725+
begin
726+
itlb_updating <= 0;
727+
if (itlb_flush_set == {addr_itlb_index_width{1'b0}})
728+
itlb_state <= `LM32_TLB_STATE_CHECK;
729+
itlb_flush_set <= itlb_flush_set - 1'b1;
730+
end
731+
732+
endcase
733+
end
734+
end
735+
736+
assign switch_to_kernel_mode = (/*(kernel_mode_reg == `LM32_KERNEL_MODE) && */csr_write_enable && (csr == `LM32_CSR_TLB_CTRL) && csr_write_data[5:0] == {`LM32_TLB_CTRL_SWITCH_TO_KERNEL_MODE, 1'b0});
737+
assign switch_to_user_mode = (/*(kernel_mode_reg == `LM32_KERNEL_MODE) && */csr_write_enable && (csr == `LM32_CSR_TLB_CTRL) && csr_write_data[5:0] == {`LM32_TLB_CTRL_SWITCH_TO_USER_MODE, 1'b0});
738+
739+
reg go_to_user_mode;
740+
reg go_to_user_mode_2;
741+
742+
always @(posedge clk_i `CFG_RESET_SENSITIVITY)
743+
begin
744+
if (rst_i == `TRUE)
745+
go_to_user_mode <= `FALSE;
746+
else
747+
go_to_user_mode <= (eret_q_x || switch_to_user_mode);
748+
end
749+
750+
always @(posedge clk_i `CFG_RESET_SENSITIVITY)
751+
begin
752+
if (rst_i == `TRUE)
753+
go_to_user_mode_2 <= `FALSE;
754+
else
755+
go_to_user_mode_2 <= go_to_user_mode;
756+
end
757+
758+
always @(posedge clk_i `CFG_RESET_SENSITIVITY)
759+
begin
760+
if (rst_i == `TRUE)
761+
kernel_mode_reg <= `LM32_KERNEL_MODE;
762+
else
763+
begin
764+
if (exception_x || switch_to_kernel_mode)
765+
kernel_mode_reg <= `LM32_KERNEL_MODE;
766+
else if (go_to_user_mode_2)
767+
kernel_mode_reg <= `LM32_USER_MODE;
768+
end
769+
end
770+
444771
generate
445772
if (bytes_per_line > 4)
446773
begin

Diff for: ‎lm32_instruction_unit.v

+39-4
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ module lm32_instruction_unit (
9999
branch_target_x,
100100
`endif
101101
exception_m,
102+
exception_x,
102103
branch_taken_m,
103104
branch_mispredict_taken_m,
104105
branch_target_m,
@@ -115,6 +116,10 @@ module lm32_instruction_unit (
115116
irom_address_xm,
116117
irom_we_xm,
117118
`endif
119+
csr,
120+
csr_write_data,
121+
csr_write_enable,
122+
eret_q_x,
118123
`ifdef CFG_IWB_ENABLED
119124
// From Wishbone
120125
i_dat_i,
@@ -143,6 +148,8 @@ module lm32_instruction_unit (
143148
`ifdef CFG_IROM_ENABLED
144149
irom_data_m,
145150
`endif
151+
itlb_miss,
152+
csr_read_data,
146153
`ifdef CFG_IWB_ENABLED
147154
// To Wishbone
148155
i_dat_o,
@@ -245,6 +252,13 @@ input [`LM32_BYTE_RNG] jtag_write_data; // JTAG wrirte data
245252
input [`LM32_WORD_RNG] jtag_address; // JTAG read/write address
246253
`endif
247254

255+
input exception_x; // An exception occured in the X stage
256+
input eret_q_x;
257+
258+
input [`LM32_CSR_RNG] csr; // CSR read/write index
259+
input [`LM32_WORD_RNG] csr_write_data; // Data to write to specified CSR
260+
input csr_write_enable; // CSR write enable
261+
248262
/////////////////////////////////////////////////////
249263
// Outputs
250264
/////////////////////////////////////////////////////
@@ -327,6 +341,12 @@ wire [`LM32_INSTRUCTION_RNG] instruction_f;
327341
output [`LM32_INSTRUCTION_RNG] instruction_d; // D stage instruction to be decoded
328342
reg [`LM32_INSTRUCTION_RNG] instruction_d;
329343

344+
output csr_read_data;
345+
wire [`LM32_WORD_RNG] csr_read_data;
346+
347+
output itlb_miss;
348+
wire itlb_miss;
349+
330350
/////////////////////////////////////////////////////
331351
// Internal nets and registers
332352
/////////////////////////////////////////////////////
@@ -340,6 +360,7 @@ reg [`LM32_PC_RNG] restart_address; // Address to restart fr
340360
`ifdef CFG_ICACHE_ENABLED
341361
wire icache_read_enable_f; // Indicates if instruction cache miss is valid
342362
wire [`LM32_PC_RNG] icache_refill_address; // Address that caused cache miss
363+
wire [`LM32_PC_RNG] icache_physical_refill_address; // Physical address that caused cache miss
343364
reg icache_refill_ready; // Indicates when next word of refill data is ready to be written to cache
344365
reg [`LM32_INSTRUCTION_RNG] icache_refill_data; // Next word of refill data, fetched from Wishbone
345366
wire [`LM32_INSTRUCTION_RNG] icache_data_f; // Instruction fetched from instruction cache
@@ -373,6 +394,9 @@ reg jtag_access; // Indicates if a JTAG W
373394
reg alternate_eba_taken;
374395
`endif
375396

397+
wire [`LM32_WORD_RNG] physical_address;
398+
wire kernel_mode;
399+
376400
/////////////////////////////////////////////////////
377401
// Functions
378402
/////////////////////////////////////////////////////
@@ -454,13 +478,24 @@ lm32_icache #(
454478
.refill_ready (icache_refill_ready),
455479
.refill_data (icache_refill_data),
456480
.iflush (iflush),
481+
.csr (csr),
482+
.csr_write_data (csr_write_data),
483+
.csr_write_enable (csr_write_enable),
484+
.exception_x (exception_x),
485+
.eret_q_x (eret_q_x),
486+
.exception_m (exception_m),
457487
// ----- Outputs -----
458488
.stall_request (icache_stall_request),
459489
.restart_request (icache_restart_request),
460490
.refill_request (icache_refill_request),
461491
.refill_address (icache_refill_address),
492+
.physical_refill_address (icache_physical_refill_address),
462493
.refilling (icache_refilling),
463-
.inst (icache_data_f)
494+
.inst (icache_data_f),
495+
.itlb_miss_int (itlb_miss),
496+
.kernel_mode (kernel_mode),
497+
.pa (physical_address),
498+
.csr_read_data (csr_read_data)
464499
);
465500
`endif
466501

@@ -555,21 +590,21 @@ generate
555590
assign first_cycle_type = `LM32_CTYPE_END;
556591
assign next_cycle_type = `LM32_CTYPE_END;
557592
assign last_word = `TRUE;
558-
assign first_address = icache_refill_address;
593+
assign first_address = icache_physical_refill_address;
559594
end
560595
8:
561596
begin
562597
assign first_cycle_type = `LM32_CTYPE_INCREMENTING;
563598
assign next_cycle_type = `LM32_CTYPE_END;
564599
assign last_word = i_adr_o[addr_offset_msb:addr_offset_lsb] == 1'b1;
565-
assign first_address = {icache_refill_address[`LM32_PC_WIDTH+2-1:addr_offset_msb+1], {addr_offset_width{1'b0}}};
600+
assign first_address = {icache_physical_refill_address[`LM32_PC_WIDTH+2-1:addr_offset_msb+1], {addr_offset_width{1'b0}}};
566601
end
567602
16:
568603
begin
569604
assign first_cycle_type = `LM32_CTYPE_INCREMENTING;
570605
assign next_cycle_type = i_adr_o[addr_offset_msb] == 1'b1 ? `LM32_CTYPE_END : `LM32_CTYPE_INCREMENTING;
571606
assign last_word = i_adr_o[addr_offset_msb:addr_offset_lsb] == 2'b11;
572-
assign first_address = {icache_refill_address[`LM32_PC_WIDTH+2-1:addr_offset_msb+1], {addr_offset_width{1'b0}}};
607+
assign first_address = {icache_physical_refill_address[`LM32_PC_WIDTH+2-1:addr_offset_msb+1], {addr_offset_width{1'b0}}};
573608
end
574609
endcase
575610
endgenerate

0 commit comments

Comments
 (0)
Please sign in to comment.