blob: a01e407b931c83e29ba0cf94e8fdc9a828568bf3 [file] [log] [blame]
module OutputRegister #(
parameter WIDTH = 32,
parameter ADDRESS = 8'b0,
parameter DEFAULT = 32'b0
)(
input wire clk,
input wire rst,
// Peripheral Bus
input wire enable,
input wire peripheralBus_we,
input wire peripheralBus_oe,
input wire[11:0] peripheralBus_address,
input wire[3:0] peripheralBus_byteSelect,
output wire[31:0] peripheralBus_dataRead,
input wire[31:0] peripheralBus_dataWrite,
output wire requestOutput,
output wire[WIDTH-1:0] currentValue
);
localparam WRITE_ADDRESS = 4'h0;
localparam SET_ADDRESS = 4'h4;
localparam CLEAR_ADDRESS = 4'h8;
localparam TOGGLE_ADDRESS = 4'hC;
wire enableWrite = peripheralBus_address[3:0] == WRITE_ADDRESS;
wire enableSet = peripheralBus_address[3:0] == SET_ADDRESS;
wire enableClear = peripheralBus_address[3:0] == CLEAR_ADDRESS;
wire enableToggle = peripheralBus_address[3:0] == TOGGLE_ADDRESS;
wire[31:0] dataMask = {
peripheralBus_byteSelect[3] ? 8'hFF : 8'h00,
peripheralBus_byteSelect[2] ? 8'hFF : 8'h00,
peripheralBus_byteSelect[1] ? 8'hFF : 8'h00,
peripheralBus_byteSelect[0] ? 8'hFF : 8'h00
};
reg[WIDTH-1:0] registerValue;
wire[31:0] maskedDataWrite = peripheralBus_dataWrite & dataMask;
wire[31:0] writeData = maskedDataWrite | (registerValue & ~dataMask);
wire[31:0] setData = registerValue | maskedDataWrite;
wire[31:0] clearData = registerValue & ~maskedDataWrite;
wire[31:0] toggleData = registerValue ^ maskedDataWrite;
wire registerSelect = enable && (peripheralBus_address[11:4] == ADDRESS);
wire we = registerSelect && peripheralBus_we && !peripheralBus_oe;
wire oe = registerSelect && peripheralBus_oe && !peripheralBus_we;
always @(posedge clk) begin
if (rst) begin
registerValue <= DEFAULT;
end else begin
if (we) begin
if (enableWrite) registerValue <= writeData[WIDTH-1:0];
else if (enableSet) registerValue <= setData;
else if (enableClear) registerValue <= clearData;
else if (enableToggle) registerValue <= toggleData;
end
end
end
wire[31:0] baseReadData;
generate
if (WIDTH == 32) begin
assign baseReadData = registerValue;
end else begin
wire[32-WIDTH-1:0] zeroPadding = 'b0;
assign baseReadData = { zeroPadding, registerValue };
end
endgenerate
assign peripheralBus_dataRead = oe ? baseReadData & dataMask : 32'b0;
assign requestOutput = oe;
assign currentValue = registerValue;
endmodule