From d4e84c58eda60b2a8084952d781ea16c53a61cf5 Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 11 Mar 2021 23:18:33 -0500 Subject: [PATCH] 64-bit AMO debugged --- wally-pipelined/src/ebu/ahblite.sv | 4 ++- wally-pipelined/src/ebu/amoalu.sv | 28 +++++++++++++------ wally-pipelined/src/ieu/controller.sv | 2 +- .../testbench/testbench-imperas.sv | 1 + 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/wally-pipelined/src/ebu/ahblite.sv b/wally-pipelined/src/ebu/ahblite.sv index 500ea492b..ed353595c 100644 --- a/wally-pipelined/src/ebu/ahblite.sv +++ b/wally-pipelined/src/ebu/ahblite.sv @@ -159,7 +159,9 @@ module ahblite ( generate if (`A_SUPPORTED) begin logic [`XLEN-1:0] AMOResult; - amoalu amoalu(.a(HRDATA), .b(WriteDataM), .funct(Funct7M), .width(MemSizeM), +// amoalu amoalu(.a(HRDATA), .b(WriteDataM), .funct(Funct7M), .width(MemSizeM), +// .result(AMOResult)); + amoalu amoalu(.srca(ReadDataPreW), .srcb(WriteDataM), .funct(Funct7M), .width(MemSizeM), .result(AMOResult)); mux2 #(`XLEN) wdmux(WriteDataM, AMOResult, AtomicM[1], WriteData); end else diff --git a/wally-pipelined/src/ebu/amoalu.sv b/wally-pipelined/src/ebu/amoalu.sv index 59d9f6927..8acba98cc 100644 --- a/wally-pipelined/src/ebu/amoalu.sv +++ b/wally-pipelined/src/ebu/amoalu.sv @@ -26,12 +26,15 @@ `include "wally-config.vh" module amoalu ( - input logic [`XLEN-1:0] a, b, + input logic [`XLEN-1:0] srca, srcb, input logic [6:0] funct, input logic [1:0] width, output logic [`XLEN-1:0] result); - logic [`XLEN-1:0] y; + logic [`XLEN-1:0] a, b, y; + + // *** can this be muxed into the regular ALU to avoid needing a second one? Only a good + // idea if the regular ALU is not the critical path // *** see how synthesis generates this and optimize more structurally if necessary to share hardware // a single carry chain should be shared for + and the four min/max @@ -43,22 +46,31 @@ module amoalu ( 5'b00100: y = a ^ b; // amoxor 5'b01100: y = a & b; // amoand 5'b01000: y = a | b; // amoor - 5'b10000: y = (a < b) ? a : b; // amomin - 5'b10100: y = (a >= b) ? a : b; // amomax - 5'b11000: y = ({1'b0, a} < {1'b0, b}) ? a : b; // amominu - 5'b11100: y = ({1'b0, a} >= {1'b0, b}) ? a : b; // amomaxu + 5'b10000: y = ($signed(a) < $signed(b)) ? a : b; // amomin + 5'b10100: y = ($signed(a) >= $signed(b)) ? a : b; // amomax + 5'b11000: y = ($unsigned(a) < $unsigned(b)) ? a : b; // amominu + 5'b11100: y = ($unsigned(a) >= $unsigned(b)) ? a : b; // amomaxu default: y = 'bx; // undefined; *** could change to b for efficiency endcase // sign extend if necessary generate if (`XLEN == 32) begin + assign a = srca; + assign b = srcb; assign result = y; end else begin // `XLEN = 64 always_comb - if (width == 2'b10) // sign-extend word-length operations + if (width == 2'b10) begin // sign-extend word-length operations + // *** it would be more efficient to look at carry out of bit 31 to determine comparisons than do this big mux on and b + a = {{32{srca[31]}}, srca[31:0]}; + b = {{32{srcb[31]}}, srcb[31:0]}; result = {{32{y[31]}}, y[31:0]}; - else result = y; + end else begin + a = srca; + b = srcb; + result = y; + end end endgenerate diff --git a/wally-pipelined/src/ieu/controller.sv b/wally-pipelined/src/ieu/controller.sv index cf8c3e17e..a1be47ad9 100644 --- a/wally-pipelined/src/ieu/controller.sv +++ b/wally-pipelined/src/ieu/controller.sv @@ -119,7 +119,7 @@ module controller( else if (InstrD[31:27] == 5'b00011) ControlsD = `CTRLW'b1_101_01_01_101_0_00_0_0_0_0_0_0_01_0; // sc else - ControlsD = `CTRLW'b1_101_00_11_001_0_00_0_0_0_0_0_0_10_0;; // amo + ControlsD = `CTRLW'b1_101_01_11_001_0_00_0_0_0_0_0_0_10_0;; // amo end else ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_1; // non-implemented instruction 7'b0110011: if (Funct7D == 7'b0000000 || Funct7D == 7'b0100000) diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index 50ef7c93b..fd0c073ee 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -38,6 +38,7 @@ module testbench(); //logic [31:0] InstrW; logic [`XLEN-1:0] meminit; string tests64a[] = '{ + "rv64a/WALLY-AMO", "2110", "rv64a/WALLY-LRSC", "2110" }; string tests64m[] = '{