/*`timescale 1ns / 1ns ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 02/24/2021 08:03:07 PM // Design Name: // Module Name: sc_decoder_fsm // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// `define BITS 8 module sc_decoder_fsm #(parameter BITS=8, N=11'd16)( input clk, rst, input in_valid, input signed [N-1:0][BITS-1:0]y, input [N-1:0]f, output logic [N-1:0]u_cap, output logic [N-1:0]v_final, output logic out_valid ); // Function to calculate f(r1,r2) = sgn(r1) * sgn(r2) * min(|r1|,|r2|) function void fminsum_calc; input signed [`BITS-1:0] a; input signed [`BITS-1:0] b; output signed [`BITS-1:0] c; logic [`BITS-2:0] abs_a; logic [`BITS-2:0] abs_b; logic [`BITS-2:0] abs_c; // Mod value of a and b abs_a = (a[`BITS-1]) ? ~a[`BITS-2:0] + 1'b1 : a[`BITS-2:0]; abs_b = (b[`BITS-1]) ? ~b[`BITS-2:0] + 1'b1 : b[`BITS-2:0]; // Multiplication of sign i.e. XOR c[`BITS-1] = a[`BITS-1] ^ b[`BITS-1]; // Minimum value between a and b abs_c = (abs_b < abs_a) ? abs_b : abs_a; // Final Minsum of a and b c[`BITS-2:0] = (c[`BITS-1]) ? ~abs_c + 1'b1 : abs_c; endfunction // Function to Calculate g(r1,r2,u) = r2 + ((1-2u) * r1) function void g_calc; input signed [`BITS-1:0] a; input signed [`BITS-1:0] b; input u; output signed [`BITS:0] c; // when u == 0 => c = b - a // When u == 1 => c = b + a c = u ? (b + (~a+1)) : (b + a) ; endfunction //parameters and signals declarations localparam d=$clog2(N); //N=4, d=2(0 & 1) logic [N-1:0]u; logic [d:0]temp_index_f,temp_index_g; reg signed [BITS-1:0] LRU[2]; reg [N-1:0]v; logic [N-1:0][BITS-1:0]L_in, L_out; logic [N-1:0]v_in, v_out; logic ena_v,enb_v,wea_v; logic ena_L,enb_L,wea_L; logic [1:0]counter,counter_reg; logic [11:0]jL1,jL2,jR1,jR2,jR3,jU1,jU2; logic [4:0] c_state, n_state; wire [N-1:0]u_cap_1; wire [N-1:0]v_final_1; //wire out_valid_1; //Auxiliary registers declarations logic [d:0] depth,depth_reg; logic [d:0] node,node_reg; logic [11:0]tmp_L,tmp_L_reg, tmp_R,tmp_R_reg,tmp_U, tmp_U_reg; //FSM States localparam idle=5'd0, root=5'd1, wait_L_logic=5'd2, wait_L=5'd3, state_L=5'd4, wait_R_logic=5'd5, wait_R=5'd6, state_R=5'd7; localparam wait_U_logic=5'd8, wait_U=5'd9, state_U=5'd10,wait_LRU_logic=5'd11, wait_LRU=5'd12, state_LRU=5'd13; localparam wait_lnode_logic=5'd14, wait_lnode=5'd15, state_lnode=5'd16,wait_lstate_logic=5'd17, wait_lstate=5'd18, state_last=5'd19; //BlockRAM Instantiations bram_v #(.ADDR_WIDTH(d-1),.DATA_WIDTH(N),.DEPTH(2**(d-1))) bram_v_i ( .clk(clk),.ena(ena_v),.enb(enb_v), .addra(depth_reg-1'b1), .addrb(depth_reg), .wea(wea_v), .dia(v_in), .dob(v_out) ); bram_L #(.ADDR_WIDTH(d-1),.DATA_WIDTH(N*BITS),.DEPTH(2**(d-1)),.N(N)) bram_L_i ( .clk(clk),.ena(ena_L),.enb(enb_L), .addra(depth_reg), .addrb(depth_reg-1'b1), .wea(wea_L), .dia(L_in), .dob(L_out) ); //output assignment for(genvar i=0; i>(2**(depth+1)))*((2*(node)+1)-((2**(depth+1))-1))); jL1=(tmp_L_reg)+temp_index_f; jL2=(tmp_L_reg)+temp_index_f+(N/(2**depth)); // jL2=(tmp_L_reg)+temp_index_f+(N>>(2**depth)); fminsum_calc(L_out[jL1],L_out[jL2],L_in[jL1]); if(tmp_L< (N/(2**depth))) // if(tmp_L< (N>>(2**depth))) n_state=state_L; else if(depth0 && node%2==0) else if(depth>0 && node[0]==0) n_state = wait_U_logic; else if(depth>0 && node!=0) n_state=wait_R_logic; else n_state=wait_lstate_logic; end wait_LRU_logic: begin depth=depth_reg; node=(node_reg-1)/2; // depth=depth_reg; node=(node_reg-1)>>1; n_state=wait_LRU; end wait_LRU: begin ena_L=0;wea_L=0;enb_L=1; ena_v=0;wea_v=0; enb_v=0; n_state=state_LRU; end state_LRU: begin ena_L=0;wea_L=0;enb_L=0; ena_v=1;wea_v=1; enb_v=0; temp_index_f=((N/(2**(depth)))*((2*node+1)-((2**(depth))-1))); // temp_index_f=((N>>(2**(depth)))*((2*node+1)-((2**(depth))-1))); fminsum_calc(L_out[temp_index_f],L_out[temp_index_f+1],LRU[0]); // u[(2*node)+2-N]=(f[(2*node)+2-N]==1) ? 0 : ((LRU[0][BITS-1] == 1) ? 1 : 0); u[(2*node)+2-N]=(f[(2*node)+2-N]) ? 0 : ((LRU[0][BITS-1]) ? 1 : 0); g_calc(L_out[temp_index_f],L_out[temp_index_f+1],u[(2*node)+2-N],LRU[1]); // u[(2*node)+3-N]=(f[(2*node)+3-N]==1) ? 0 : ((LRU[1][BITS-1] == 1) ? 1 : 0); u[(2*node)+3-N]=(f[(2*node)+3-N]) ? 0 : ((LRU[1][BITS-1]) ? 1 : 0); v_in[temp_index_f]=u[(2*node)+2-N] ^ u[(2*node)+3-N]; v_in[temp_index_f+1]=u[(2*node)+3-N]; // if(node%2==1) if(node[0]) n_state = wait_R_logic; else n_state=wait_U_logic; end wait_lnode_logic: begin depth=depth_reg+1; node=node_reg; n_state=wait_lnode; end wait_lnode: begin ena_L=0;wea_L=0;enb_L=1; ena_v=0;wea_v=0; enb_v=0; n_state=state_lnode; end state_lnode: begin ena_L=0;wea_L=0;enb_L=0; ena_v=1;wea_v=1; enb_v=0; temp_index_f=((N/(2**(depth)))*((2*node+1)-((2**(depth))-1))); // temp_index_f=((N>>(2**(depth)))*((2*node+1)-((2**(depth))-1))); fminsum_calc(L_out[temp_index_f],L_out[temp_index_f+1],LRU[0]); // u[(2*node)+2-N]=(f[(2*node)+2-N]==1) ? 0 : ((LRU[0][BITS-1] == 1) ? 1 : 0); u[(2*node)+2-N]=(f[(2*node)+2-N]) ? 0 : ((LRU[0][BITS-1]) ? 1 : 0); g_calc(L_out[temp_index_f],L_out[temp_index_f+1],u[(2*node)+2-N],LRU[1]); // u[(2*node)+3-N]=(f[(2*node)+3-N]==1) ? 0 : ((LRU[1][BITS-1] == 1) ? 1 : 0); u[(2*node)+3-N]=(f[(2*node)+3-N]) ? 0 : ((LRU[1][BITS-1]) ? 1 : 0); v_in[temp_index_f]=u[(2*node)+2-N] ^ u[(2*node)+3-N]; v_in[temp_index_f+1]=u[(2*node)+3-N]; n_state = wait_U_logic; end wait_lstate_logic: begin depth=depth_reg; node=node_reg; n_state=wait_lstate; end wait_lstate: begin ena_L=0;wea_L=0;enb_L=1; ena_v=0;wea_v=0; enb_v=0; n_state=state_last; end state_last: begin ena_L=0;wea_L=0;enb_L=0; ena_v=1;wea_v=1; enb_v=0; v=v_out; n_state=idle; end endcase else n_state = idle; end endmodule */ `timescale 1ns / 1ns ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 02/24/2021 08:03:07 PM // Design Name: // Module Name: sc_decoder_fsm // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// `define BITS 8 module sc_decoder_fsm #(parameter BITS=8, N=11'd128)( input clk, rst, input in_valid, input signed [N-1:0][BITS-1:0] y, input [N-1:0]f, output wire [N-1:0]u_cap, output wire [N-1:0]v_final, output wire out_valid ); //function for fminsum calculation function void fminsum_calc; input signed [`BITS-1:0] a; input signed [`BITS-1:0] b; output signed [`BITS-1:0] c; logic [`BITS-2:0] abs_a; logic [`BITS-2:0] abs_b; logic [`BITS-2:0] abs_c; abs_a = (a[`BITS-1]) ? ~a[`BITS-2:0] + 1'b1 : a[`BITS-2:0]; abs_b = (b[`BITS-1]) ? ~b[`BITS-2:0] + 1'b1 : b[`BITS-2:0]; c[`BITS-1] = a[`BITS-1] ^ b[`BITS-1]; abs_c = (abs_b < abs_a) ? abs_b : abs_a; c[`BITS-2:0] = (c[`BITS-1]) ? ~abs_c + 1'b1 : abs_c; endfunction //function for g-value calculation function void g_calc; input signed [`BITS-1:0] a; input signed [`BITS-1:0] b; input u; output signed [`BITS:0] c; c = (u == 0) ? (b + a) : (b + (~a+1'b1)); endfunction //parameters and signals declarations localparam d=$clog2(N); //N=4, d=2(0 & 1) //localparam n=2*N-1; //(2**d)-1; //localparam cmax=0; logic u[N]; logic [d:0]temp_index_f,temp_index_g; reg signed [BITS-1:0] LRU[2]; reg [N-1:0]v; logic [N-1:0][BITS-1:0]L_in, L_out; logic [N-1:0]v_in, v_out; logic ena_v,enb_v,wea_v; logic ena_L,enb_L,wea_L; //logic [1:0]counter,counter_reg; logic [11:0]jL1,jL2,jR1,jR2,jR3,jU1,jU2; logic [4:0] c_state, n_state; //Auxiliary registers declarations logic [d:0] depth,depth_reg; logic [d:0] node,node_reg; logic [11:0]tmp_L,tmp_L_reg, tmp_R,tmp_R_reg,tmp_U, tmp_U_reg; //FSM States localparam idle=5'd0, root=5'd1, wait_L_logic=5'd2, wait_L=5'd3, state_L=5'd4, wait_R_logic=5'd5, wait_R=5'd6, state_R=5'd7; localparam wait_U_logic=5'd8, wait_U=5'd9, state_U=5'd10,wait_LRU_logic=5'd11, wait_LRU=5'd12, state_LRU=5'd13; localparam wait_lnode_logic=5'd14, wait_lnode=5'd15, state_lnode=5'd16,wait_lstate_logic=5'd17, wait_lstate=5'd18, state_last=5'd19; //BlockRAM Instantiations bram_v #(.ADDR_WIDTH(d-1),.DATA_WIDTH(N),.DEPTH(2**(d-1))) bram_v_i ( .clk(clk),.ena(ena_v),.enb(enb_v), .addra(depth_reg-1), .addrb(depth_reg), .wea(wea_v), .dia(v_in), .dob(v_out) ); bram_L #(.ADDR_WIDTH(d-1),.DATA_WIDTH(N*BITS),.DEPTH(2**(d-1)),.N(N)) bram_L_i ( .clk(clk),.ena(ena_L),.enb(enb_L), .addra(depth_reg), .addrb(depth_reg-1), .wea(wea_L), .dia(L_in), .dob(L_out) ); //output assignment for(genvar i=0; i>1; tmp_U=0; n_state=wait_U; end wait_U: begin ena_L=0;wea_L=0;enb_L=0; ena_v=0;wea_v=0; enb_v=1'b1; // if(counter==cmax) begin // counter=counter_reg-cmax; n_state=state_U; // end // else // counter=counter_reg+1; end state_U: begin ena_L=0;wea_L=0;enb_L=0; ena_v=1'b1;wea_v=1'b1; enb_v=0; tmp_U=tmp_U_reg+1'b1; temp_index_f=((N/(2**(depth)))*((2*node+1'b1)-((2**(depth))-1'b1))); jU1=(tmp_U_reg)+temp_index_f; jU2=(tmp_U_reg)+temp_index_f+(N/(2**(depth))); v_in[jU1] = v_out[jU1] ^ v_out[jU2]; v_in[jU2] = v_out[jU2]; if(tmp_U<(N/(2**(depth)))) n_state=state_U; else if(depth>0 && ~node[0]) n_state = wait_U_logic; else if(depth>0 && node!=0) n_state=wait_R_logic; else n_state=wait_lstate_logic; end wait_LRU_logic: begin // depth=depth_reg; node=(node_reg-1'b1)/2; depth=depth_reg; node=(node_reg-1'b1)>>1; n_state=wait_LRU; end wait_LRU: begin ena_L=0;wea_L=0;enb_L=1'b1; ena_v=0;wea_v=0; enb_v=0; // if(counter==cmax) begin // counter=counter_reg-cmax; n_state=state_LRU; // end // else // counter=counter_reg+1; end state_LRU: begin ena_L=0;wea_L=0;enb_L=0; ena_v=1'b1;wea_v=1'b1; enb_v=0; temp_index_f=((N/(2**(depth)))*((2*node+1'b1)-((2**(depth))-1'b1))); fminsum_calc(L_out[temp_index_f],L_out[temp_index_f+1],LRU[0]); // u[(2*node)+2-N]=(f[(2*node)+2-N]==1) ? 0 : ((LRU[0][BITS-1] == 1) ? 1 : 0); u[(2*node)+2-N]=(f[(2*node)+2-N]) ? 0 : ((LRU[0][BITS-1]) ? 1 : 0); g_calc(L_out[temp_index_f],L_out[temp_index_f+1],u[(2*node)+2-N],LRU[1]); //u[(2*node)+3-N]=(f[(2*node)+3-N]==1) ? 0 : ((LRU[1][BITS-1] == 1) ? 1 : 0); u[(2*node)+3-N]=(f[(2*node)+3-N]) ? 0 : ((LRU[1][BITS-1]) ? 1 : 0); v_in[temp_index_f]=u[(2*node)+2-N] ^ u[(2*node)+3-N]; v_in[temp_index_f+1]=u[(2*node)+3-N]; // if(node[0]==1) if(node[0]) n_state = wait_R_logic; else n_state=wait_U_logic; end wait_lnode_logic: begin depth=depth_reg+1'b1; node=node_reg; n_state=wait_lnode; end wait_lnode: begin ena_L=0;wea_L=0;enb_L=1'b1; ena_v=0;wea_v=0; enb_v=0; // if(counter==cmax) begin // counter=counter_reg-cmax; n_state=state_lnode; // end // else // counter=counter_reg+1; end state_lnode: begin ena_L=0;wea_L=0;enb_L=0; ena_v=1'b1;wea_v=1'b1; enb_v=0; temp_index_f=((N/(2**(depth)))*((2*node+1'b1)-((2**(depth))-1'b1))); fminsum_calc(L_out[temp_index_f],L_out[temp_index_f+1],LRU[0]); // u[(2*node)+2-N]=(f[(2*node)+2-N]==1'b1) ? 0 : ((LRU[0][BITS-1] == 1'b1) ? 1'b1 : 0); u[(2*node)+2-N]=(f[(2*node)+2-N]) ? 0 : ((LRU[0][BITS-1]) ? 1'b1 : 0); g_calc(L_out[temp_index_f],L_out[temp_index_f+1],u[(2*node)+2-N],LRU[1]); // u[(2*node)+3-N]=(f[(2*node)+3-N]==1'b1) ? 0 : ((LRU[1][BITS-1] == 1) ? 1'b1 : 0); u[(2*node)+3-N]=(f[(2*node)+3-N]) ? 0 : ((LRU[1][BITS-1]) ? 1'b1 : 0); v_in[temp_index_f]=u[(2*node)+2-N] ^ u[(2*node)+3-N]; v_in[temp_index_f+1]=u[(2*node)+3-N]; n_state = wait_U_logic; end wait_lstate_logic: begin depth=depth_reg; node=node_reg; n_state=wait_lstate; end wait_lstate: begin ena_L=0;wea_L=0;enb_L=1'b1; ena_v=0;wea_v=0; enb_v=0; // if(counter==cmax) begin // counter=counter_reg-cmax; n_state=state_last; // end // else // counter=counter_reg+1; end state_last: begin ena_L=0;wea_L=0;enb_L=0; ena_v=1'b1;wea_v=1'b1; enb_v=0; v=v_out; n_state=idle; end endcase else n_state = idle; end endmodule