Skip to content

Commit

Permalink
FPGA: Move RAM address and data scrambling into the RAM module.
Browse files Browse the repository at this point in the history
	Move the logic implementing the RAM address and data
	scrambling, descrambling into the RAM module. This cleans up
	the top level, and makes it easier to change the scrambling
	without chaning the top. In order to do correct scrambling the
	address to the RAM core must be 16 bits, not 15.

	Clean up some minor details at the top level, fixing text
        aligment and grouping of ports in instances.

Signed-off-by: Joachim Strömbergson <[email protected]>
  • Loading branch information
secworks authored and dehanj committed Aug 29, 2024
1 parent 8d4ad12 commit 03e834d
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 21 deletions.
2 changes: 1 addition & 1 deletion hw/application_fpga/application_fpga.bin.sha256
Original file line number Diff line number Diff line change
@@ -1 +1 @@
42746c6d9d879ad975874fb51b3d4e031578dac9a0e7ddd4b10a1d3efa34c6c7 application_fpga.bin
83c821bc60613ef7394750d377dee188629e751847cd57d7089c243e2192c266 application_fpga.bin
57 changes: 43 additions & 14 deletions hw/application_fpga/core/ram/rtl/ram.v
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
// iCE40UP 5K device. This creates a single 32-bit wide,
// 128 kByte large memory.
//
// The block also implements data and address scrambling controlled
// by the ram_addr_rand and ram_data_rand seeds.
//
//
// Author: Joachim Strombergson
// Copyright (C) 2022 - Tillitis AB
// SPDX-License-Identifier: GPL-2.0-only
Expand All @@ -17,9 +21,13 @@
module ram(
input wire clk,
input wire reset_n,

input wire [14 : 0] ram_addr_rand,
input wire [31 : 0] ram_data_rand,

input wire cs,
input wire [03 : 0] we,
input wire [14 : 0] address,
input wire [15 : 0] address,
input wire [31 : 0] write_data,
output wire [31 : 0] read_data,
output wire ready
Expand All @@ -29,28 +37,32 @@ module ram(
//----------------------------------------------------------------
// Registers and wires.
//----------------------------------------------------------------
reg ready_reg;
reg ready_reg;

reg cs0;
reg cs1;
reg [31 : 0] read_data0;
reg [31 : 0] read_data1;
reg [31 : 0] muxed_read_data;

reg [14 : 0] scrambled_ram_addr;
reg [31 : 0] scrambled_write_data;
reg [31 : 0] descrambled_read_data;


//----------------------------------------------------------------
// Concurrent assignment of ports.
//----------------------------------------------------------------
assign read_data = muxed_read_data;
assign read_data = descrambled_read_data;
assign ready = ready_reg;


//----------------------------------------------------------------
// SPRAM instances.
//----------------------------------------------------------------
SB_SPRAM256KA spram0(
.ADDRESS(address[13:0]),
.DATAIN(write_data[15:0]),
.ADDRESS(scrambled_ram_addr[13:0]),
.DATAIN(scrambled_write_data[15:0]),
.MASKWREN({we[1], we[1], we[0], we[0]}),
.WREN(we[1] | we[0]),
.CHIPSELECT(cs0),
Expand All @@ -62,8 +74,8 @@ module ram(
);

SB_SPRAM256KA spram1(
.ADDRESS(address[13:0]),
.DATAIN(write_data[31:16]),
.ADDRESS(scrambled_ram_addr[13:0]),
.DATAIN(scrambled_write_data[31:16]),
.MASKWREN({we[3], we[3], we[2], we[2]}),
.WREN(we[3] | we[2]),
.CHIPSELECT(cs0),
Expand All @@ -76,8 +88,8 @@ module ram(


SB_SPRAM256KA spram2(
.ADDRESS(address[13:0]),
.DATAIN(write_data[15:0]),
.ADDRESS(scrambled_ram_addr[13:0]),
.DATAIN(scrambled_write_data[15:0]),
.MASKWREN({we[1], we[1], we[0], we[0]}),
.WREN(we[1] | we[0]),
.CHIPSELECT(cs1),
Expand All @@ -89,8 +101,8 @@ module ram(
);

SB_SPRAM256KA spram3(
.ADDRESS(address[13:0]),
.DATAIN(write_data[31:16]),
.ADDRESS(scrambled_ram_addr[13:0]),
.DATAIN(scrambled_write_data[31:16]),
.MASKWREN({we[3], we[3], we[2], we[2]}),
.WREN(we[3] | we[2]),
.CHIPSELECT(cs1),
Expand Down Expand Up @@ -120,15 +132,32 @@ module ram(
end


//----------------------------------------------------------------
// scramble_descramble
//
// Scramble address and write data, and descramble read data using
// the ram_addr_rand and ram_data_rand seeds.
//----------------------------------------------------------------
always @*
begin: scramble_descramble
scrambled_ram_addr = address[14 : 0] ^ ram_addr_rand;
scrambled_write_data = write_data ^ ram_data_rand ^ {2{address}};
descrambled_read_data = muxed_read_data ^ ram_data_rand ^ {2{address}};
end


//----------------------------------------------------------------
// mem_mux
//
// Select which of the data read from the banks should be
// returned during a read access.
//----------------------------------------------------------------
always @*
begin : mem_mux
cs0 = ~address[14] & cs;
cs1 = address[14] & cs;
cs0 = ~scrambled_ram_addr[14] & cs;
cs1 = scrambled_ram_addr[14] & cs;

if (address[14]) begin
if (scrambled_ram_addr[14]) begin
muxed_read_data = read_data1;
end else begin
muxed_read_data = read_data0;
Expand Down
1 change: 0 additions & 1 deletion hw/application_fpga/firmware.bin.sha512
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
edb39fca7dafb8ea0b89fdeecd960d7656e14ce461e49af97160a8bd6e67d9987e816adad37ba0fcfa63d107c3160988e4c3423ce4a71c39544bc0045888fec1 firmware.bin

18 changes: 13 additions & 5 deletions hw/application_fpga/rtl/application_fpga.v
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ module application_fpga(

reg ram_cs;
reg [3 : 0] ram_we;
reg [14 : 0] ram_address;
reg [15 : 0] ram_address;
reg [31 : 0] ram_write_data;
wire [31 : 0] ram_read_data;
wire ram_ready;
Expand Down Expand Up @@ -181,6 +181,7 @@ module application_fpga(
.mem_wdata(cpu_wdata),
.mem_wstrb(cpu_wstrb),
.mem_rdata(muxed_rdata_reg),
.mem_instr(cpu_instr),

// Defined unused ports. Makes lint happy. But
// we still needs to help lint with empty ports.
Expand All @@ -189,7 +190,6 @@ module application_fpga(
.eoi(),
.trace_valid(),
.trace_data(),
.mem_instr(cpu_instr),
.mem_la_read(),
.mem_la_write(),
.mem_la_addr(),
Expand Down Expand Up @@ -222,6 +222,9 @@ module application_fpga(
.clk(clk),
.reset_n(reset_n),

.ram_addr_rand(ram_addr_rand),
.ram_data_rand(ram_data_rand),

.cs(ram_cs),
.we(ram_we),
.address(ram_address),
Expand Down Expand Up @@ -394,8 +397,8 @@ module application_fpga(

ram_cs = 1'h0;
ram_we = 4'h0;
ram_address = cpu_addr[16 : 2] ^ ram_addr_rand;
ram_write_data = cpu_wdata ^ ram_data_rand ^ {2{cpu_addr[15 : 0]}};
ram_address = cpu_addr[17 : 2];
ram_write_data = cpu_wdata;

fw_ram_cs = 1'h0;
fw_ram_we = cpu_wstrb;
Expand Down Expand Up @@ -429,6 +432,10 @@ module application_fpga(
tk1_address = cpu_addr[9 : 2];
tk1_write_data = cpu_wdata;


// Two stage mux implementing read and
// write access performed based on the address
// from the CPU.
if (cpu_valid && !muxed_ready_reg) begin
if (force_trap) begin
muxed_rdata_new = ILLEGAL_INSTRUCTION;
Expand All @@ -445,7 +452,7 @@ module application_fpga(
RAM_PREFIX: begin
ram_cs = 1'h1;
ram_we = cpu_wstrb;
muxed_rdata_new = ram_read_data ^ ram_data_rand ^ {2{cpu_addr[15 : 0]}};
muxed_rdata_new = ram_read_data;
muxed_ready_new = ram_ready;
end

Expand Down Expand Up @@ -513,6 +520,7 @@ module application_fpga(
end
end
end

endmodule // application_fpga

//======================================================================
Expand Down

0 comments on commit 03e834d

Please sign in to comment.