data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v
1: b'%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:34: Cannot find include file: jedro_1_defines.v\n`include "jedro_1_defines.v" \n         ^~~~~~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl,data/full_repos/permissive/522553437/jedro_1_defines.v\n             data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl,data/full_repos/permissive/522553437/jedro_1_defines.v.v\n             data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl,data/full_repos/permissive/522553437/jedro_1_defines.v.sv\n             jedro_1_defines.v\n             jedro_1_defines.v.v\n             jedro_1_defines.v.sv\n             obj_dir/jedro_1_defines.v\n             obj_dir/jedro_1_defines.v.v\n             obj_dir/jedro_1_defines.v.sv\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:43: Define or directive not defined: \'`LSU_CTRL_WIDTH\'\n  input  wire  [`LSU_CTRL_WIDTH-1:0] ctrl_i,\n                ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:44: Define or directive not defined: \'`DATA_WIDTH\'\n  input  wire  [`DATA_WIDTH-1:0]     addr_i,            \n                ^~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:45: Define or directive not defined: \'`DATA_WIDTH\'\n  input  wire  [`DATA_WIDTH-1:0]     wdata_i,           \n                ^~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:46: Define or directive not defined: \'`REG_ADDR_WIDTH\'\n  input  wire  [`REG_ADDR_WIDTH-1:0] regdest_i,         \n                ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:49: Define or directive not defined: \'`DATA_WIDTH\'\n  output reg  [`DATA_WIDTH-1:0]     rdata_ro,        \n               ^~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:51: Define or directive not defined: \'`REG_ADDR_WIDTH\'\n  output reg  [`REG_ADDR_WIDTH-1:0] regdest_ro,\n               ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:56: Define or directive not defined: \'`DATA_WIDTH\'\n  output reg  [`DATA_WIDTH-1:0]     exception_addr_ro,\n               ^~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:61: Define or directive not defined: \'`DATA_WIDTH\'\n  output reg  [`DATA_WIDTH-1:0]     ram_addr,\n               ^~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:62: Define or directive not defined: \'`DATA_WIDTH\'\n  output reg  [`DATA_WIDTH-1:0]     ram_wdata,\n               ^~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:63: Define or directive not defined: \'`DATA_WIDTH\'\n  input  wire [`DATA_WIDTH-1:0]     ram_rdata,\n               ^~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:69: Define or directive not defined: \'`DATA_WIDTH\'\nreg  [`DATA_WIDTH-1:0]     data_r;  \n      ^~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:70: Define or directive not defined: \'`DATA_WIDTH\'\nwire [`DATA_WIDTH-1:0]     byte_sign_extended_w;\n      ^~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:71: Define or directive not defined: \'`DATA_WIDTH\'\nwire [`DATA_WIDTH-1:0]     hword_sign_extended_w;\n      ^~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:75: Define or directive not defined: \'`LSU_CTRL_WIDTH\'\nreg  [`LSU_CTRL_WIDTH-1:0] ctrl_save_r;\n      ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:92: Define or directive not defined: \'`LSU_LOAD_BYTE\'\n            `LSU_LOAD_BYTE        : misaligned_load = 1\'b0;\n            ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:92: syntax error, unexpected \':\', expecting endcase\n            `LSU_LOAD_BYTE        : misaligned_load = 1\'b0;\n                                  ^\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:93: Define or directive not defined: \'`LSU_LOAD_BYTE_U\'\n            `LSU_LOAD_BYTE_U      : misaligned_load = 1\'b0;\n            ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:94: Define or directive not defined: \'`LSU_LOAD_HALF_WORD\'\n            `LSU_LOAD_HALF_WORD   : misaligned_load = addr_i[0];\n            ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:95: Define or directive not defined: \'`LSU_LOAD_HALF_WORD_U\'\n            `LSU_LOAD_HALF_WORD_U : misaligned_load = addr_i[0];\n            ^~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:96: Define or directive not defined: \'`LSU_LOAD_WORD\'\n            `LSU_LOAD_WORD        : misaligned_load = |addr_i[1:0];\n            ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:97: Define or directive not defined: \'`LSU_STORE_BYTE\'\n            `LSU_STORE_BYTE       : misaligned_store = 1\'b0;\n            ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:98: Define or directive not defined: \'`LSU_STORE_HALF_WORD\'\n            `LSU_STORE_HALF_WORD  : misaligned_store = addr_i[0];\n            ^~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:99: Define or directive not defined: \'`LSU_STORE_WORD\'\n            `LSU_STORE_WORD       : misaligned_store = |addr_i[1:0];\n            ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:149: Define or directive not defined: \'`DATA_WIDTH\'\nreg  [`DATA_WIDTH/8 - 1:0] we;  \n      ^~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:149: syntax error, unexpected \'/\', expecting TYPE-IDENTIFIER\nreg  [`DATA_WIDTH/8 - 1:0] we;  \n                 ^\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:151: Define or directive not defined: \'`LSU_CTRL_WIDTH\'\nassign is_write = ctrl_i[`LSU_CTRL_WIDTH-1];\n                         ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:164: Define or directive not defined: \'`LSU_STORE_BYTE\'\n        if      (ctrl_i == `LSU_STORE_BYTE) begin\n                           ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:164: syntax error, unexpected \')\', expecting TYPE-IDENTIFIER\n        if      (ctrl_i == `LSU_STORE_BYTE) begin\n                                          ^\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:182: syntax error, unexpected else\n        else if (ctrl_i == `LSU_STORE_HALF_WORD) begin\n        ^~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:182: Define or directive not defined: \'`LSU_STORE_HALF_WORD\'\n        else if (ctrl_i == `LSU_STORE_HALF_WORD) begin\n                           ^~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:302: Define or directive not defined: \'`LSU_LOAD_BYTE\'\n    if (ctrl_save_r == `LSU_LOAD_BYTE ||\n                       ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:302: syntax error, unexpected ||, expecting TYPE-IDENTIFIER\n    if (ctrl_save_r == `LSU_LOAD_BYTE ||\n                                      ^~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:303: Define or directive not defined: \'`LSU_LOAD_BYTE_U\'\n        ctrl_save_r == `LSU_LOAD_BYTE_U) begin\n                       ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:313: Define or directive not defined: \'`LSU_LOAD_HALF_WORD\'\n    else if (ctrl_save_r == `LSU_LOAD_HALF_WORD ||\n                            ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:314: Define or directive not defined: \'`LSU_LOAD_HALF_WORD_U\'\n             ctrl_save_r == `LSU_LOAD_HALF_WORD_U) begin\n                            ^~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:322: Define or directive not defined: \'`DATA_WIDTH\'\nsign_extender #(.N(`DATA_WIDTH), .M(8)) sign_extender_byte(.in_i(active_byte),\n                   ^~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:324: Define or directive not defined: \'`DATA_WIDTH\'\nsign_extender #(.N(`DATA_WIDTH), .M(16)) sign_extender_halfword(.in_i(active_hword),\n                   ^~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:334: Define or directive not defined: \'`LSU_LOAD_BYTE\'\n            `LSU_LOAD_BYTE:        rdata_ro = byte_sign_extended_w;\n            ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:334: syntax error, unexpected \':\', expecting endcase\n            `LSU_LOAD_BYTE:        rdata_ro = byte_sign_extended_w;\n                          ^\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:335: Define or directive not defined: \'`LSU_LOAD_BYTE_U\'\n            `LSU_LOAD_BYTE_U:      rdata_ro = {24\'b0, active_byte};\n            ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:336: Define or directive not defined: \'`LSU_LOAD_HALF_WORD\'\n            `LSU_LOAD_HALF_WORD:   rdata_ro = hword_sign_extended_w;\n            ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:337: Define or directive not defined: \'`LSU_LOAD_HALF_WORD_U\'\n            `LSU_LOAD_HALF_WORD_U: rdata_ro = {16\'b0, active_hword};\n            ^~~~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/522553437/verilog/rtl/riscv-jedro-1/rtl/jedro_1_lsu.v:338: Define or directive not defined: \'`LSU_LOAD_WORD\'\n            `LSU_LOAD_WORD:        rdata_ro = data_r;\n            ^~~~~~~~~~~~~~\n%Error: Exiting due to 44 error(s)\n'
module jedro_1_lsu
(
  input wire clk_i,
  input wire rstn_i,
  

  input  wire                        ctrl_valid_i,
  input  wire  [`LSU_CTRL_WIDTH-1:0] ctrl_i,
  input  wire  [`DATA_WIDTH-1:0]     addr_i,
  input  wire  [`DATA_WIDTH-1:0]     wdata_i,
  input  wire  [`REG_ADDR_WIDTH-1:0] regdest_i,
 

  output reg  [`DATA_WIDTH-1:0]     rdata_ro,
  output reg                        rf_wb_ro,
  output reg  [`REG_ADDR_WIDTH-1:0] regdest_ro,

  output reg                        misaligned_load_ro,
  output reg                        misaligned_store_ro,
  output reg                        bus_error_ro,
  output reg  [`DATA_WIDTH-1:0]     exception_addr_ro,


  output reg  [3:0]                 ram_we,
  output reg                        ram_stb,
  output reg  [`DATA_WIDTH-1:0]     ram_addr,
  output reg  [`DATA_WIDTH-1:0]     ram_wdata,
  input  wire [`DATA_WIDTH-1:0]     ram_rdata,
  input  wire                       ram_ack,
  input  wire                       ram_err
);


reg  [`DATA_WIDTH-1:0]     data_r;
wire [`DATA_WIDTH-1:0]     byte_sign_extended_w;
wire [`DATA_WIDTH-1:0]     hword_sign_extended_w;
reg  [7:0]                 active_byte;
reg  [15:0]                active_hword;
reg  [1:0]                 byte_addr_r;
reg  [`LSU_CTRL_WIDTH-1:0] ctrl_save_r;

reg [31:0]                 active_write_word;

reg                        misaligned_load;
reg                        misaligned_load_hold;
reg                        misaligned_store;



always@(*) begin
    if (ctrl_valid_i == 1'b1) begin
        misaligned_load  = 1'b0;
        misaligned_store = 1'b0;
        casez (ctrl_i)
            `LSU_LOAD_BYTE        : misaligned_load = 1'b0;
            `LSU_LOAD_BYTE_U      : misaligned_load = 1'b0;
            `LSU_LOAD_HALF_WORD   : misaligned_load = addr_i[0];
            `LSU_LOAD_HALF_WORD_U : misaligned_load = addr_i[0];
            `LSU_LOAD_WORD        : misaligned_load = |addr_i[1:0];
            `LSU_STORE_BYTE       : misaligned_store = 1'b0;
            `LSU_STORE_HALF_WORD  : misaligned_store = addr_i[0];
            `LSU_STORE_WORD       : misaligned_store = |addr_i[1:0];
			default				  : misaligned_load = 1'b0;
        endcase
    end
    else begin
        misaligned_load  = 1'b0;
        misaligned_store = 1'b0;
    end
end


always @(posedge clk_i) begin
    if (rstn_i == 1'b0) begin
        misaligned_load_ro  <= 1'b0;
        misaligned_store_ro <= 1'b0;
    end
    else begin
            misaligned_load_ro  <= misaligned_load;
            misaligned_store_ro <= misaligned_store;
    end
end

always @(posedge clk_i) begin
    if (rstn_i == 1'b0) begin
        misaligned_load_hold <= 0; 
    end
    else begin
        if (ctrl_valid_i) 
            misaligned_load_hold <= misaligned_load;
        else              
            misaligned_load_hold <= misaligned_load_hold;
    end
end

always @(posedge clk_i) begin
    if (rstn_i == 1'b0) begin
        exception_addr_ro <= 0;
    end
    else begin
        if (ctrl_valid_i)   exception_addr_ro <= addr_i;
        else                exception_addr_ro <= exception_addr_ro;
    end
end



wire is_write;
reg  is_write_hold;
reg  [`DATA_WIDTH/8 - 1:0] we;

assign is_write = ctrl_i[`LSU_CTRL_WIDTH-1];

always @(posedge clk_i) begin
    if (rstn_i == 1'b0) is_write_hold <= 0; 
    else begin
        if (ctrl_valid_i) is_write_hold <= is_write;
        else              is_write_hold <= is_write_hold;
    end
end

always@(*) begin
    active_write_word = 0;
    if (is_write == 1'b1) begin
        if      (ctrl_i == `LSU_STORE_BYTE) begin
            if      (addr_i[1:0] == 2'b00) begin      
                active_write_word = {24'b0, wdata_i[7:0]};
                we = 4'b0001;
            end
            else if (addr_i[1:0] == 2'b01) begin
                active_write_word = {16'b0, wdata_i[7:0], 8'b0};
                we = 4'b0010;
            end
            else if (addr_i[1:0] == 2'b10) begin
                active_write_word = {8'b0, wdata_i[7:0], 16'b0};
                we = 4'b0100;
            end
            else begin
                active_write_word = {wdata_i[7:0], 24'b0};
                we = 4'b1000;
            end
        end
        else if (ctrl_i == `LSU_STORE_HALF_WORD) begin
            if (addr_i[1:0] == 2'b00) begin
                active_write_word = {16'b0, wdata_i[15:0]};
                we = 4'b0011; 
            end
            else begin
                active_write_word = {wdata_i[15:0], 16'b0};
                we = 4'b1100; 
            end
        end
        else begin
            active_write_word = wdata_i;
            we = 4'b1111;
        end
    end
    else begin
        we = 4'b0000;
    end
end





always @(posedge clk_i) begin
    if (rstn_i == 1'b0) begin
        ctrl_save_r <= 0;
    end
    else begin
        if (ctrl_valid_i == 1'b1)
            ctrl_save_r <= ctrl_i;
        else
            ctrl_save_r <= ctrl_save_r;
    end
end



always @(posedge clk_i) begin
    if (rstn_i == 1'b0) begin
        regdest_ro <= 0;
    end
    else begin
        regdest_ro <= regdest_i;
    end
end



always @(posedge clk_i) begin
    if (rstn_i == 1'b0) begin
        byte_addr_r <= 2'b00;
    end
    else begin
        if (ctrl_valid_i & (~is_write) ) 
            byte_addr_r <= addr_i[1:0];
        else
            byte_addr_r <= byte_addr_r;
    end
end



always @(posedge clk_i) begin
    if (rstn_i == 1'b0) begin
        data_r <= 0;
    end
    else begin
        if (ram_ack & (~is_write_hold))
            data_r <= ram_rdata;
        else
            data_r <= data_r;
    end
end


always @(posedge clk_i) begin
	if (~rstn_i) begin
		ram_stb <= 1'b0;
    	ram_addr <= 0;
    	ram_we <= 0;
    	ram_wdata <= 0; 
	end
	else begin
		if (~ram_stb) begin
			ram_stb  <= ctrl_valid_i;
       		ram_addr <= addr_i;
			ram_we   <= we & {4{ctrl_valid_i&(~misaligned_store)}}; 
       		ram_wdata <= active_write_word;
		end
		else if (ram_ack) begin
			ram_stb   <= 0;
			ram_addr  <= 0;
			ram_we    <= 0;
			ram_wdata <= 0;
		end
		else begin
			ram_stb   <= ram_stb;
			ram_addr  <= ram_addr;
			ram_we    <= ram_we;
			ram_wdata <= ram_wdata;
		end
	end
end



always@(*) begin
    active_byte  = 8'b00000000;
    active_hword = 16'b00000000_00000000;
    if (ctrl_save_r == `LSU_LOAD_BYTE ||
        ctrl_save_r == `LSU_LOAD_BYTE_U) begin
        if      (byte_addr_r == 2'b00) 
            active_byte = data_r[7:0];
        else if (byte_addr_r == 2'b01)
            active_byte = data_r[15:8];
        else if (byte_addr_r == 2'b10)
            active_byte = data_r[23:16];
        else
            active_byte = data_r[31:24];
    end
    else if (ctrl_save_r == `LSU_LOAD_HALF_WORD ||
             ctrl_save_r == `LSU_LOAD_HALF_WORD_U) begin
        if (byte_addr_r == 2'b00)
            active_hword = data_r[15:0];
        else 
            active_hword = data_r[31:16];
    end
end

sign_extender #(.N(`DATA_WIDTH), .M(8)) sign_extender_byte(.in_i(active_byte),
                                                          .out_o(byte_sign_extended_w));
sign_extender #(.N(`DATA_WIDTH), .M(16)) sign_extender_halfword(.in_i(active_hword),
                                                               .out_o(hword_sign_extended_w));

always@(*) begin
    if (is_write == 1'b1) begin
        rdata_ro = 0;
    end 
    else begin
        rdata_ro = 0;
        casez (ctrl_save_r)
            `LSU_LOAD_BYTE:        rdata_ro = byte_sign_extended_w;
            `LSU_LOAD_BYTE_U:      rdata_ro = {24'b0, active_byte};
            `LSU_LOAD_HALF_WORD:   rdata_ro = hword_sign_extended_w;
            `LSU_LOAD_HALF_WORD_U: rdata_ro = {16'b0, active_hword};
            `LSU_LOAD_WORD:        rdata_ro = data_r;
            default:               rdata_ro = 0;
        endcase
    end
end



always @(posedge clk_i) begin
    if (rstn_i == 1'b0) rf_wb_ro <= 0;
    else                rf_wb_ro <= ram_ack & (~is_write_hold) & (~misaligned_load_hold); 
end

always @(posedge clk_i) begin
    if (rstn_i == 1'b0) bus_error_ro <= 0;
    else                bus_error_ro <= ram_err;
end


endmodule
module jedro_1_lsu
(
  input wire clk_i,
  input wire rstn_i,
  

  input  wire                        ctrl_valid_i,
  input  wire  [`LSU_CTRL_WIDTH-1:0] ctrl_i,
  input  wire  [`DATA_WIDTH-1:0]     addr_i,
  input  wire  [`DATA_WIDTH-1:0]     wdata_i,
  input  wire  [`REG_ADDR_WIDTH-1:0] regdest_i,
 

  output reg  [`DATA_WIDTH-1:0]     rdata_ro,
  output reg                        rf_wb_ro,
  output reg  [`REG_ADDR_WIDTH-1:0] regdest_ro,

  output reg                        misaligned_load_ro,
  output reg                        misaligned_store_ro,
  output reg                        bus_error_ro,
  output reg  [`DATA_WIDTH-1:0]     exception_addr_ro,


  output reg  [3:0]                 ram_we,
  output reg                        ram_stb,
  output reg  [`DATA_WIDTH-1:0]     ram_addr,
  output reg  [`DATA_WIDTH-1:0]     ram_wdata,
  input  wire [`DATA_WIDTH-1:0]     ram_rdata,
  input  wire                       ram_ack,
  input  wire                       ram_err
);



reg  [`DATA_WIDTH-1:0]     data_r;
wire [`DATA_WIDTH-1:0]     byte_sign_extended_w;
wire [`DATA_WIDTH-1:0]     hword_sign_extended_w;
reg  [7:0]                 active_byte;
reg  [15:0]                active_hword;
reg  [1:0]                 byte_addr_r;
reg  [`LSU_CTRL_WIDTH-1:0] ctrl_save_r;

reg [31:0]                 active_write_word;

reg                        misaligned_load;
reg                        misaligned_load_hold;
reg                        misaligned_store;



always@(*) begin
    if (ctrl_valid_i == 1'b1) begin
        misaligned_load  = 1'b0;
        misaligned_store = 1'b0;
        casez (ctrl_i)
            `LSU_LOAD_BYTE        : misaligned_load = 1'b0;
            `LSU_LOAD_BYTE_U      : misaligned_load = 1'b0;
            `LSU_LOAD_HALF_WORD   : misaligned_load = addr_i[0];
            `LSU_LOAD_HALF_WORD_U : misaligned_load = addr_i[0];
            `LSU_LOAD_WORD        : misaligned_load = |addr_i[1:0];
            `LSU_STORE_BYTE       : misaligned_store = 1'b0;
            `LSU_STORE_HALF_WORD  : misaligned_store = addr_i[0];
            `LSU_STORE_WORD       : misaligned_store = |addr_i[1:0];
			default				  : misaligned_load = 1'b0;
        endcase
    end
    else begin
        misaligned_load  = 1'b0;
        misaligned_store = 1'b0;
    end
end


always @(posedge clk_i) begin
    if (rstn_i == 1'b0) begin
        misaligned_load_ro  <= 1'b0;
        misaligned_store_ro <= 1'b0;
    end
    else begin
            misaligned_load_ro  <= misaligned_load;
            misaligned_store_ro <= misaligned_store;
    end
end

always @(posedge clk_i) begin
    if (rstn_i == 1'b0) begin
        misaligned_load_hold <= 0; 
    end
    else begin
        if (ctrl_valid_i) 
            misaligned_load_hold <= misaligned_load;
        else              
            misaligned_load_hold <= misaligned_load_hold;
    end
end

always @(posedge clk_i) begin
    if (rstn_i == 1'b0) begin
        exception_addr_ro <= 0;
    end
    else begin
        if (ctrl_valid_i)   exception_addr_ro <= addr_i;
        else                exception_addr_ro <= exception_addr_ro;
    end
end



wire is_write;
reg  is_write_hold;
reg  [`DATA_WIDTH/8 - 1:0] we;

assign is_write = ctrl_i[`LSU_CTRL_WIDTH-1];

always @(posedge clk_i) begin
    if (rstn_i == 1'b0) is_write_hold <= 0; 
    else begin
        if (ctrl_valid_i) is_write_hold <= is_write;
        else              is_write_hold <= is_write_hold;
    end
end

always@(*) begin
    active_write_word = 0;
    if (is_write == 1'b1) begin
        if      (ctrl_i == `LSU_STORE_BYTE) begin
            if      (addr_i[1:0] == 2'b00) begin      
                active_write_word = {24'b0, wdata_i[7:0]};
                we = 4'b0001;
            end
            else if (addr_i[1:0] == 2'b01) begin
                active_write_word = {16'b0, wdata_i[7:0], 8'b0};
                we = 4'b0010;
            end
            else if (addr_i[1:0] == 2'b10) begin
                active_write_word = {8'b0, wdata_i[7:0], 16'b0};
                we = 4'b0100;
            end
            else begin
                active_write_word = {wdata_i[7:0], 24'b0};
                we = 4'b1000;
            end
        end
        else if (ctrl_i == `LSU_STORE_HALF_WORD) begin
            if (addr_i[1:0] == 2'b00) begin
                active_write_word = {16'b0, wdata_i[15:0]};
                we = 4'b0011; 
            end
            else begin
                active_write_word = {wdata_i[15:0], 16'b0};
                we = 4'b1100; 
            end
        end
        else begin
            active_write_word = wdata_i;
            we = 4'b1111;
        end
    end
    else begin
        we = 4'b0000;
    end
end





always @(posedge clk_i) begin
    if (rstn_i == 1'b0) begin
        ctrl_save_r <= 0;
    end
    else begin
        if (ctrl_valid_i == 1'b1)
            ctrl_save_r <= ctrl_i;
        else
            ctrl_save_r <= ctrl_save_r;
    end
end



always @(posedge clk_i) begin
    if (rstn_i == 1'b0) begin
        regdest_ro <= 0;
    end
    else begin
        regdest_ro <= regdest_i;
    end
end



always @(posedge clk_i) begin
    if (rstn_i == 1'b0) begin
        byte_addr_r <= 2'b00;
    end
    else begin
        if (ctrl_valid_i & (~is_write) ) 
            byte_addr_r <= addr_i[1:0];
        else
            byte_addr_r <= byte_addr_r;
    end
end



always @(posedge clk_i) begin
    if (rstn_i == 1'b0) begin
        data_r <= 0;
    end
    else begin
        if (ram_ack & (~is_write_hold))
            data_r <= ram_rdata;
        else
            data_r <= data_r;
    end
end


always @(posedge clk_i) begin
	if (~rstn_i) begin
		ram_stb <= 1'b0;
    	ram_addr <= 0;
    	ram_we <= 0;
    	ram_wdata <= 0; 
	end
	else begin
		if (~ram_stb) begin
			ram_stb  <= ctrl_valid_i;
       		ram_addr <= addr_i;
			ram_we   <= we & {4{ctrl_valid_i&(~misaligned_store)}}; 
       		ram_wdata <= active_write_word;
		end
		else if (ram_ack) begin
			ram_stb   <= 0;
			ram_addr  <= 0;
			ram_we    <= 0;
			ram_wdata <= 0;
		end
		else begin
			ram_stb   <= ram_stb;
			ram_addr  <= ram_addr;
			ram_we    <= ram_we;
			ram_wdata <= ram_wdata;
		end
	end
end



always@(*) begin
    active_byte  = 8'b00000000;
    active_hword = 16'b00000000_00000000;
    if (ctrl_save_r == `LSU_LOAD_BYTE ||
        ctrl_save_r == `LSU_LOAD_BYTE_U) begin
        if      (byte_addr_r == 2'b00) 
            active_byte = data_r[7:0];
        else if (byte_addr_r == 2'b01)
            active_byte = data_r[15:8];
        else if (byte_addr_r == 2'b10)
            active_byte = data_r[23:16];
        else
            active_byte = data_r[31:24];
    end
    else if (ctrl_save_r == `LSU_LOAD_HALF_WORD ||
             ctrl_save_r == `LSU_LOAD_HALF_WORD_U) begin
        if (byte_addr_r == 2'b00)
            active_hword = data_r[15:0];
        else 
            active_hword = data_r[31:16];
    end
end

sign_extender #(.N(`DATA_WIDTH), .M(8)) sign_extender_byte(.in_i(active_byte),
                                                          .out_o(byte_sign_extended_w));
sign_extender #(.N(`DATA_WIDTH), .M(16)) sign_extender_halfword(.in_i(active_hword),
                                                               .out_o(hword_sign_extended_w));

always@(*) begin
    if (is_write == 1'b1) begin
        rdata_ro = 0;
    end 
    else begin
        rdata_ro = 0;
        casez (ctrl_save_r)
            `LSU_LOAD_BYTE:        rdata_ro = byte_sign_extended_w;
            `LSU_LOAD_BYTE_U:      rdata_ro = {24'b0, active_byte};
            `LSU_LOAD_HALF_WORD:   rdata_ro = hword_sign_extended_w;
            `LSU_LOAD_HALF_WORD_U: rdata_ro = {16'b0, active_hword};
            `LSU_LOAD_WORD:        rdata_ro = data_r;
            default:               rdata_ro = 0;
        endcase
    end
end



always @(posedge clk_i) begin
    if (rstn_i == 1'b0) rf_wb_ro <= 0;
    else                rf_wb_ro <= ram_ack & (~is_write_hold) & (~misaligned_load_hold); 
end

always @(posedge clk_i) begin
    if (rstn_i == 1'b0) bus_error_ro <= 0;
    else                bus_error_ro <= ram_err;
end


endmodule