From 9adc0e5bad01f34f6cf6b6d53019ead30ba49945 Mon Sep 17 00:00:00 2001 From: Wojciech Kosior Date: Mon, 14 Sep 2020 17:21:55 +0200 Subject: add ability to make non-aligned loads/stores and loads/stores of 1 or 2 bytes together with test bench --- design/stack_machine.v | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) (limited to 'design') diff --git a/design/stack_machine.v b/design/stack_machine.v index b6c2706..54eae5e 100644 --- a/design/stack_machine.v +++ b/design/stack_machine.v @@ -22,7 +22,7 @@ module stack_machine_new output reg [20:0] D_ADR_O, input wire [31:0] D_DAT_I, output reg [31:0] D_DAT_O, - output reg [3:0] D_SEL_O, /* We'll start using it soon */ + output reg [3:0] D_SEL_O, output reg D_STB_O, output reg D_CYC_O, output reg D_WE_O, @@ -37,8 +37,6 @@ module stack_machine_new if (CLK_I || !CLK_I) begin /* avoiding "found no sensitivities" warning */ I_DAT_O = 16'bx; I_WE_O = 1'b0; - - D_SEL_O = 4'hF; /* This one is temporary */ end end @@ -161,16 +159,25 @@ module stack_machine_new wire word_operation; wire dword_operation; wire qword_operation; /* We won't implement these in hw */ + wire [3:0] instruction_select_mask; assign byte_operation = instruction[9:8] == 2'b00; assign word_operation = instruction[9:8] == 2'b01; assign dword_operation = instruction[9:8] == 2'b10; assign qword_operation = instruction[9:8] == 2'b11; + assign instruction_select_mask = byte_operation ? 4'b0001 : + word_operation ? 4'b0011 : + 4'b1111; /* Flag mainly meant for load instructions, but not exclusively */ wire sign_extend; assign sign_extend = instruction[7]; + wire loaded_value_sign; + assign loaded_value_sign = !sign_extend ? 0 : + byte_operation ? D_DAT_I[7] : + word_operation ? D_DAT_I[15] : 1'bx; + /* Instructions other than load and store go here */ /* Instructions, that do not change stack size */ @@ -382,14 +389,14 @@ module stack_machine_new if (load) begin D_ADR_O <= addr_to_use; D_DAT_O <= 32'bx; - /* D_SEL_O <= ????; */ /* We'll later set this one */ + D_SEL_O <= instruction_select_mask; D_STB_O <= 1; D_CYC_O <= 1; D_WE_O <= 0; end else if (store) begin D_ADR_O <= addr_to_use; D_DAT_O <= r1; - /* D_SEL_O <= ????; */ /* We'll later set this one */ + D_SEL_O <= instruction_select_mask; D_STB_O <= 1; D_CYC_O <= 1; D_WE_O <= 1; @@ -397,7 +404,7 @@ module stack_machine_new `SET_SP(sp + 4); D_ADR_O <= sp; D_DAT_O <= 32'bx; - /* D_SEL_O <= 4'hF; */ + D_SEL_O <= 4'b1111; D_STB_O <= 1; D_CYC_O <= 1; D_WE_O <= 0; @@ -405,7 +412,7 @@ module stack_machine_new `SET_SP(sp - 4); D_ADR_O <= sp - 4; D_DAT_O <= r0; - /* D_SEL_O <= 4'hF; */ + D_SEL_O <= 4'b1111; D_STB_O <= 1; D_CYC_O <= 1; D_WE_O <= 1; @@ -433,21 +440,21 @@ module stack_machine_new `SET_SP(sp + 4); D_ADR_O <= sp; D_DAT_O <= 32'bx; - /* D_SEL_O <= 4'hF; */ + D_SEL_O <= 4'b1111; D_STB_O <= 1; D_WE_O <= 0; end else if (stack_grows) begin `SET_SP(sp - 4); D_ADR_O <= sp - 4; D_DAT_O <= stack_put_value; - /* D_SEL_O <= 4'hF; */ + D_SEL_O <= 4'b1111; D_STB_O <= 1; D_WE_O <= 1; end end else begin // if (load_store_unrequested ||... D_ADR_O <= 21'bx; D_DAT_O <= 32'bx; - /* D_SEL_O <= 4'bx; */ + D_SEL_O <= 4'bx; D_STB_O <= 0; D_WE_O <= 0; end // else: !if(load_store_unrequested ||... @@ -475,8 +482,14 @@ module stack_machine_new if (stack_grows && first_execution_tick) r0 <= r1; - if (load && load_store_uncompleted) - r1 <= D_DAT_I; + if (load && load_store_uncompleted) begin + if (byte_operation) + r1 <= {{24{loaded_value_sign}}, D_DAT_I[7:0]}; + else if (word_operation) + r1 <= {{16{loaded_value_sign}}, D_DAT_I[15:0]}; + else + r1 <= D_DAT_I; + end if (!first_execution_tick && use_im) im <= 32'bx; -- cgit v1.2.3