module rt (clk,
reset,
inp_strb,
inp,
busy,
outp_strb,
outp,
t_data,
t_addr,
t_we);
input clk, reset, inp_strb;
input [29:0] inp; // rout_req_t
// 24 bits addr [28:5]
// 5 bits segment [4:0]
// 1 bit command 0 -> store, 1 -> find
output busy;
output outp_strb;
output [28:0] outp; // tlb_entry_t
// 24 bits addr [28:5]
// 5 bits segment [4:0]
reg busy;
reg outp_strb;
reg [28:0] outp;
reg [29:0] req; // rout_req_t
reg [4:0] old_tlb_index; // tlb_index_t
reg [4:0] tlb_index;
reg [28:0] response, t2; // tlb_entry_t
reg [28:0] t1;
reg found;
reg [4:0] k;
reg [3:0] i;
//TLB RAM INTERFACE (29x32)
inout [28:0] t_data;
output [4:0] t_addr ;
output t_we ;
wire t_we;
wire [28:0] t_data ;
wire [28:0] t_data_out ;
reg [28:0] t_data_in;
//----------------------------------------------------------------------
reg [5:0] state ;
reg [5:0] next_state ;
parameter
idle =0,
initialize =1,
write_tlb_ini =2,
incrm_k =3,
ini_assert =4,
wait4_instrb =5,
read_input =6,
search =7,
search_2 =8,
search_3 =9,
search_4_read_tlb =10,
search_5 =11,
search_7 =13,
search_8_incrm_i =14,
search_9 =15,
found_check =16,
recep_found =17,
recep_not_found =18,
save =19,
save_found_check =20,
save_recep_found =21,
save_recep_not_found=22,
save_2 =23,
save_3 =24,
insert_chk_tb_index =25,
insert_2 =26,
insert_3 =27,
insert_4 =28,
insert_5_incrm_ind =29,
write_results =30,
toggle_strb =31,
deassert_busy =32,
delay =33,
change_busy =34;
//------------------------------------------------------------------------
//state machine
always @(inp_strb or state or i or k or t1 or req or
tlb_index or found )
begin
case( state)
idle : next_state <= initialize ;
initialize : next_state <= write_tlb_ini ;
write_tlb_ini : next_state <= incrm_k ;
incrm_k : if (k == 5'h1F)
next_state <= ini_assert ;
else
next_state <= write_tlb_ini ;
ini_assert : begin
next_state <= delay ;
end
delay : next_state <= wait4_instrb ;
wait4_instrb : if (inp_strb == 1'b1 )
next_state <= read_input ;
else
next_state <= wait4_instrb ;
read_input : begin
next_state <= change_busy ;
end
change_busy : begin
next_state <= search ;
end
search : next_state <= search_2 ;
search_2 : next_state <= search_3 ;
search_3 : next_state <= search_4_read_tlb ;
search_4_read_tlb : next_state <= search_5 ;
search_5 : if (t1[28:5] == req[28:5])
begin
next_state <= search_9 ;
end
else
next_state <= search_7 ;
search_7 : next_state <= search_8_incrm_i ;
search_8_incrm_i : if (i == 4'd0 )
next_state <= search_9 ;
else
next_state <= search_2 ;
search_9 : if (req[29] == 1'b1 )
next_state <= found_check ;
else
next_state <= save ;
found_check : if (found == 1'b1 )
next_state <= recep_found ;
else
next_state <= recep_not_found ;
recep_found : next_state <= write_results ;
recep_not_found : next_state <= write_results ;
save : next_state <= save_found_check ;
save_found_check : if (found == 1'b1 )
next_state <= save_recep_found ;
else
next_state <= save_recep_not_found ;
save_recep_found : next_state <= write_results ;
save_recep_not_found : next_state <= save_2 ;
save_2 : next_state <= save_3 ;
save_3 : next_state <= insert_chk_tb_index ;
insert_chk_tb_index : if (tlb_index < 32 )
next_state <= insert_2 ;
else
next_state <= write_results ;
insert_2 : next_state <= insert_3 ;
insert_3 : next_state <= insert_4 ;
insert_4 : if (t1[28:5] == 24'hFFFFFF )
next_state <= write_results ;
else
next_state <= insert_5_incrm_ind ;
insert_5_incrm_ind : next_state <= insert_chk_tb_index
;
write_results : next_state <= toggle_strb;
toggle_strb : next_state <= deassert_busy;
deassert_busy : begin
next_state <= delay;
end
endcase
end
always @(posedge clk)
begin
if (reset)
state <= idle ;
else
state <= next_state ;
end
//-----------------------------------------------------------------------
//k counter to count 32 times
always @(posedge clk )
begin
if (reset )
k <= 5'b0;
/* initialize before counting */
else if (next_state == initialize)
k <= 5'b0 ;
else if (next_state == incrm_k)
k <=k+1;
else
k <= k ;
end
//-----------------------------------------------------------------------
//i counter to count five times
always @(posedge clk )
begin
if (reset )
i <= 4'd5;
/* initialize before counting */
else if ((next_state == search) |(next_state ==search_9)
)
i <= 4'd5 ;
else if (next_state == search_8_incrm_i)
i <=i - 4'd1;
else
i <= i ;
end
//-----------------------------------------------------------------------
// TLB RAM INTERFACE
assign t_we = ((state == write_tlb_ini) |
(state == insert_3) |
(state == save_recep_found)) ;
assign t_addr = (state == write_tlb_ini) ? k : tlb_index;
always @(posedge clk)
begin
if (next_state == write_tlb_ini)
t_data_in <=t1[28:0];
else if (next_state == save_recep_found)
t_data_in <=response[28:0] ;
else if (next_state == insert_3)
t_data_in <=t2[28:0] ;
else
t_data_in <=t_data_in ;
end
assign t_data_out = t_data;
assign t_data = (t_we) ? t_data_in : 29'hZZZZ_ZZZZ;
//------------------------------------------------------------------------
//state machine operations
always @(posedge clk)
begin
if ((reset) | (next_state == write_results) )
busy <= 1'b1;
else if ((next_state== ini_assert)|(next_state == deassert_busy))
busy <= 1'b0;
else
busy <= busy;
end
//***************************************************************************
always @(posedge clk)
begin
if (reset | (next_state == delay))
found <= 1'b0 ;
else
if ((next_state == search_5) && (t1[28:5] ==
req[28:5]) )
found <= 1'b1 ;
else
found <= found ;
end
//**************************************************************************
always @(posedge clk)
begin
if (reset)
outp_strb <= 1'b0;
else if (next_state==toggle_strb)
outp_strb <= ~outp_strb ;
else
outp_strb <= outp_strb ;
end
//***********************************************************************
always @(posedge clk)
begin
if (reset)
t1 <= 29'b0;
else if (next_state == initialize)
begin
t1[28:5] <= 24'hFFFFFF;
t1[4:0] <= 5'h1F;
end
else if ((next_state == search_4_read_tlb)|
(next_state == save_recep_not_found)|
(next_state == insert_2 ))
t1 <= t_data_out ;
else
t1 <= t1 ;
end
//************************************************************************
always @(posedge clk)
begin
if (reset)
t2 <= 29'b0;
else if (next_state == save_3)
t2 <= response;
else if (next_state == insert_5_incrm_ind)
t2 <= t1;
else
t2 <= t2;
end
//**************************************************************************
always @(posedge clk)
begin
if (reset)
response <= 29'b0;
else if (next_state == recep_found)
response <= t1;
else if (next_state == recep_not_found)
begin
response[28:5] <= req[28:5] ;
response[4:0] <= 5'h1F ;
end
else if (next_state == save)
response[28:0] <= req[28:0];
else
response <= response ;
end
//***************************************************************************
always @(posedge clk)
begin
if (reset)
outp <= 29'b0;
else if (next_state == write_results)
outp <= response;
else outp <=outp ;
end
//**************************************************************************
always @(posedge clk)
begin
if (reset)
req <= 29'b0;
else if (inp_strb)
req <= inp ;
else
req <=req;
end
//***************************************************************************
always @(posedge clk)
begin
if (reset | (next_state == read_input ))
tlb_index <= 5'b0;
else if (next_state == search_3)
tlb_index <= tlb_index + (1'b1 << i);
else if ((next_state == search_7) && (t1[28:5]
> req[28:5]))
tlb_index <= old_tlb_index ;
else if (((next_state == save_3) && (t1[28:5]
< req[28:5])) |
(next_state == insert_5_incrm_ind))
tlb_index <= tlb_index + 1;
else
tlb_index <= tlb_index;
end
//****************************************************************************
always @(posedge clk)
begin
if (reset)
old_tlb_index <= 5'b0;
else if (next_state == search_2)
old_tlb_index <= tlb_index ;
else
old_tlb_index <= old_tlb_index ;
end
//****************************************************************************
endmodule