-
Notifications
You must be signed in to change notification settings - Fork 29
HyperRAM test software #437
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,251 @@ | ||
| # Copyright lowRISC contributors. | ||
| # Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| // A set of memory initialisation functions using different access sizes, to check that | ||
| // the write transactions are properly coalesced into write bursts to the HyperBus | ||
| // Memory Controller. | ||
| // | ||
| // Each routine is expected to be writing a single, defined byte to each address that is | ||
| // modified. By initialising the entirety of a target buffer to a different value first, | ||
| // the set of modified addresses may be ascertained. | ||
|
|
||
| .section .text, "ax", @progbits | ||
|
|
||
| .option norvc | ||
|
|
||
| // Byte-based memory writing. | ||
| // | ||
| // entry ca0 -> byte-aligned destination buffer | ||
| // a1 = byte to be stored | ||
| // a2 = number of bytes | ||
| // exit - | ||
| .globl hyperram_memset_b | ||
| .p2align 5 | ||
| hyperram_memset_b: | ||
| addi a2, a2, -8 | ||
| bltz a2, memset_b_8fix | ||
| memset_b_8: | ||
| csb a1, (ca0) | ||
| csb a1, 1(ca0) | ||
| csb a1, 2(ca0) | ||
| csb a1, 3(ca0) | ||
| csb a1, 4(ca0) | ||
| csb a1, 5(ca0) | ||
| csb a1, 6(ca0) | ||
| csb a1, 7(ca0) | ||
| cincoffset ca0, ca0, 8 | ||
| addi a2, a2, -8 | ||
| bgez a2, memset_b_8 | ||
| memset_b_8fix: | ||
| addi a2, a2, 8 | ||
| bgtz a2, memset_b_tail | ||
| cret | ||
|
|
||
| // Just complete the request using byte stores; this is shared among all _ascending_ routines. | ||
| // Performance is not very important, but it would be better to keep the byte writes temporally | ||
| // close together to try to provoke races. | ||
| // | ||
| // ca0 -> byte-aligned pointer into destination buffer | ||
| // a1 = byte to be stored | ||
| // a2 = non-zero count of bytes remaining | ||
| memset_b_tail: | ||
| add a2, a0, a2 | ||
| memset_b_1: | ||
| csb a1, (ca0) | ||
| cincoffset ca0, ca0, 1 | ||
| bltu a0, a2, memset_b_1 | ||
| cret | ||
|
|
||
| // Descending transfer, pre-decrementing address; shared among the two _descending_ routines. | ||
| // | ||
| // ca0 -> just beyond next address to be written, decrement before use. | ||
| // a1 = byte to be stored | ||
| // a2 = non-zero count of bytes remaining | ||
| memset_b_desc_tail: | ||
| sub a2, a0, a2 | ||
| memset_b_desc_1: | ||
| csb a1, -1(ca0) | ||
| cincoffset ca0, ca0, -1 | ||
| bgtu a0, a2, memset_b_desc_1 | ||
| cret | ||
|
|
||
| // Byte and half word-based memory writing; each word is written using | ||
| // 2 byte stores and a half-word store. | ||
| // | ||
| // entry ca0 -> word-aligned destination buffer | ||
| // a1 = byte to be stored, replicated throughout word | ||
| // a2 = number of bytes | ||
| // exit - | ||
| .globl hyperram_memset_hb | ||
| .p2align 5 | ||
| hyperram_memset_hb: | ||
| addi a2, a2, -4 | ||
| bltz a2, memset_hb_4fix | ||
| memset_hb_4: | ||
| csb a1, (ca0) | ||
| csb a1, 1(ca0) | ||
| csh a1, 2(ca0) | ||
| cincoffset ca0, ca0, 4 | ||
| addi a2, a2, -4 | ||
| bgez a2, memset_hb_4 | ||
| memset_hb_4fix: | ||
| addi a2, a2, 4 | ||
| bgtz a2, memset_b_tail | ||
| cret | ||
|
|
||
| // Half word-based memory writing. | ||
| // | ||
| // entry ca0 -> half-word aligned destination buffer | ||
| // a1 = byte to be stored, replicated throughout half-word | ||
| // a2 = number of bytes | ||
| // exit - | ||
| .globl hyperram_memset_h | ||
| .p2align 5 | ||
| hyperram_memset_h: | ||
| addi a2, a2, -16 | ||
| bltz a2, memset_h_16fix | ||
| memset_h_16: | ||
| csh a1, (ca0) | ||
| csh a1, 2(ca0) | ||
| csh a1, 4(ca0) | ||
| csh a1, 6(ca0) | ||
| csh a1, 8(ca0) | ||
| csh a1, 10(ca0) | ||
| csh a1, 12(ca0) | ||
| csh a1, 14(ca0) | ||
| cincoffset ca0, ca0, 16 | ||
| addi a2, a2, -16 | ||
| bgez a2, memset_h_16 | ||
| memset_h_16fix: | ||
| addi a2, a2, 16 | ||
| bgtz a2, memset_b_tail | ||
| cret | ||
|
|
||
| // Word-based memory writing. | ||
| // | ||
| // entry ca0 -> word-aligned destination buffer | ||
| // a1 = byte to be stored, replicated throughout word | ||
| // a2 = number of bytes | ||
| .globl hyperram_memset_w | ||
| .p2align 5 | ||
| hyperram_memset_w: | ||
| addi a2, a2, -32 | ||
| bltz a2, memset_w_32fix | ||
| memset_w_32: | ||
| csw a1, (ca0) | ||
| csw a1, 4(ca0) | ||
| csw a1, 8(ca0) | ||
| csw a1, 12(ca0) | ||
| csw a1, 16(ca0) | ||
| csw a1, 20(ca0) | ||
| csw a1, 24(ca0) | ||
| csw a1, 28(ca0) | ||
| cincoffset ca0, ca0, 32 | ||
| addi a2, a2, -32 | ||
| bgez a2, memset_w_32 | ||
| memset_w_32fix: | ||
| addi a2, a2, 32 | ||
| bgtz a2, memset_b_tail | ||
| cret | ||
|
|
||
| // Repeated words memory writing; the performance of this code is of no consequence. | ||
| // It is concerned purely with ensuring the correctness of the written data. | ||
| // | ||
| // entry ca0 -> word-aligned destination buffer | ||
| // a1 = byte to be stored, replicated throughout word | ||
| // a2 = number of bytes | ||
| .globl hyperram_memset_wr | ||
| .p2align 5 | ||
| hyperram_memset_wr: | ||
| addi a2, a2, -4 | ||
| bltz a2, memset_wr_4fix | ||
| xori a3, a1, -1 | ||
| memset_wr_4: | ||
| csw a3, (ca0) // This word should be overwritten... | ||
| csw a1, (ca0) // ...by the original value. | ||
| cincoffset ca0, ca0, 4 | ||
| addi a2, a2, -4 | ||
| bgez a2, memset_wr_4 | ||
| memset_wr_4fix: | ||
| addi a2, a2, 4 | ||
| bgtz a2, memset_b_tail | ||
| cret | ||
|
|
||
| // Word-based memory writing to descending addresses. | ||
| // | ||
| // entry ca0 -> word-aligned end of destination buffer, exclusive | ||
| // a1 = byte to be stored, replicated throughout word | ||
| // a2 = number of bytes | ||
| .globl hyperram_memset_wd | ||
| .p2align 5 | ||
| hyperram_memset_wd: | ||
| addi a2, a2, -8 | ||
| bltz a2, memset_wd_8fix | ||
| memset_wd_8: | ||
| csw a1, -4(ca0) | ||
| csw a1, -8(ca0) | ||
| cincoffset ca0, ca0, -8 | ||
| addi a2, a2, -8 | ||
| bgez a2, memset_wd_8 | ||
| memset_wd_8fix: | ||
| addi a2, a2, 8 | ||
| bgtz a2, memset_b_desc_tail | ||
| cret | ||
|
|
||
| // Capability stores to ascending addresses. | ||
| // | ||
| // These are issued as two back-to-back word writes and we're just using | ||
| // this as a way to issue 64-bit writes rather than trying to create | ||
| // sensible/valid capabilities. | ||
| // | ||
| // entry ca0 -> double-word aligned destination buffer | ||
| // a1 = byte to be stored, replicated throughout word | ||
| // a2 = number of bytes | ||
| .globl hyperram_memset_c | ||
| .p2align 5 | ||
| hyperram_memset_c: | ||
| // Replicate the data word to yield a double word. | ||
| cincoffset csp, csp, -8 | ||
| csw a1, (csp) | ||
| csw a1, 4(csp) | ||
| clc ca1,(csp) | ||
| cincoffset csp, csp, 8 | ||
| addi a2, a2, -8 | ||
| bltz a2, memset_c_8fix | ||
| memset_c_8: | ||
| csc ca1, (ca0) | ||
| cincoffset ca0, ca0, 8 | ||
| addi a2, a2, -8 | ||
| bgez a2, memset_c_8 | ||
| memset_c_8fix: | ||
| addi a2, a2, 8 | ||
| bgtz a2, memset_b_tail | ||
| cret | ||
|
|
||
| // Capability stores to descending addresses. See above. | ||
| // | ||
| // entry ca0 -> double-word aligned end of destination buffer, exclusive | ||
| // a1 = byte to be stored, replicated throughout word | ||
| // a2 = number of bytes | ||
| .globl hyperram_memset_cd | ||
| .p2align 5 | ||
| hyperram_memset_cd: | ||
| // Replicate the data word to yield a double word. | ||
| cincoffset csp, csp, -8 | ||
| csw a1, (csp) | ||
| csw a1, 4(csp) | ||
| clc ca1, (csp) | ||
| cincoffset csp, csp, 8 | ||
| addi a2, a2, -8 | ||
| bltz a2, memset_cd_8fix | ||
| memset_cd_8: | ||
| csc ca1, -8(ca0) | ||
| cincoffset ca0, ca0, -8 | ||
| addi a2, a2, -8 | ||
| bgez a2, memset_cd_8 | ||
| memset_cd_8fix: | ||
| addi a2, a2, 8 | ||
| bgtz a2, memset_b_desc_tail | ||
| cret | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| /** | ||
| * Copyright lowRISC contributors. | ||
| * Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| */ | ||
| #pragma once | ||
|
|
||
| #include <stdint.h> | ||
|
|
||
| enum WriteTestType { | ||
| WriteTestType_B = 0, | ||
| WriteTestType_H, | ||
| WriteTestType_HB, | ||
| WriteTestType_W, | ||
| WriteTestType_WR, | ||
| WriteTestType_WD, | ||
| WriteTestType_C, | ||
| WriteTestType_CD | ||
| }; | ||
|
|
||
| // Memory-writing routines; these all mimic the ISO C function `memset` except that they have | ||
| // a constraint of 'natural alignment' upon the buffer address and have very specific | ||
| // implementations to ensure defined traffic for testing the write coalescing/buffering logic | ||
| // of the HyperRAM controller interface. | ||
| extern "C" void hyperram_memset_b(volatile uint8_t *dst, int c, size_t n); | ||
| extern "C" void hyperram_memset_h(volatile uint16_t *dst, int c, size_t n); | ||
| extern "C" void hyperram_memset_hb(volatile uint16_t *dst, int c, size_t n); | ||
| extern "C" void hyperram_memset_w(volatile uint32_t *dst, int c, size_t n); | ||
| extern "C" void hyperram_memset_wr(volatile uint32_t *dst, int c, size_t n); | ||
| extern "C" void hyperram_memset_wd(volatile uint32_t *dst, int c, size_t n); | ||
| extern "C" void hyperram_memset_c(volatile uint64_t *dst, int c, size_t n); | ||
| extern "C" void hyperram_memset_cd(volatile uint64_t *dst, int c, size_t n); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason why this has an inner loop of two stores rather than the eight of the ascending version?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code was just written to perform back-to-back writes until the maximum burst length is achieved; that's just two words for a descending burst, but 8 for an ascending burst. It makes little difference in practice because the write coalescing logic will not time out and flush the burst write to HyperRAM for dozens of cycles and the Ibex will complete the loop overhead in far fewer cycles than that.