Corrects Clint module, and adds rust clint debugger
This commit is contained in:
@@ -119,6 +119,47 @@ impl VGA
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn digit_count(mut val: u64) -> u64
|
||||||
|
{
|
||||||
|
let mut i = 0;
|
||||||
|
while val != 0
|
||||||
|
{
|
||||||
|
val /= 10;
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
i
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn draw_u64(x: u16, y: u16, mut val: u64, color: Color, bg_color: Color)
|
||||||
|
{
|
||||||
|
if val == 0
|
||||||
|
{
|
||||||
|
unsafe { Self::draw_char_bg(x, y, '0', color, bg_color) }
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let digit_count = Self::digit_count(val) - 1;
|
||||||
|
let mut i = digit_count as u16;
|
||||||
|
while val != 0
|
||||||
|
{
|
||||||
|
let digit = val % 10;
|
||||||
|
val /= 10;
|
||||||
|
|
||||||
|
let char = (digit as u8) + b'0';
|
||||||
|
unsafe {
|
||||||
|
Self::draw_char_bg(
|
||||||
|
x + i * (FONT_WIDTH as u16),
|
||||||
|
y,
|
||||||
|
char as char,
|
||||||
|
color,
|
||||||
|
bg_color,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
i -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsafe fn font_plate_index(x: u16, y: u16) -> bool
|
unsafe fn font_plate_index(x: u16, y: u16) -> bool
|
||||||
{
|
{
|
||||||
let pixel_index = (y as usize) * FONTPLATE_WIDTH + (x as usize);
|
let pixel_index = (y as usize) * FONTPLATE_WIDTH + (x as usize);
|
||||||
|
|||||||
@@ -21,6 +21,15 @@ pub extern "C" fn main() -> !
|
|||||||
VGA::draw_string(10, 10, "Running RUST !", GREEN);
|
VGA::draw_string(10, 10, "Running RUST !", GREEN);
|
||||||
VGA::draw_string(10, 23, "LedIp state :", RED);
|
VGA::draw_string(10, 23, "LedIp state :", RED);
|
||||||
|
|
||||||
|
let clint_time: *mut u64 = 0x0200bff8 as *mut u64;
|
||||||
|
|
||||||
|
let clocks = *clint_time;
|
||||||
|
let seconds = clocks / (125_000_000 / 2);
|
||||||
|
VGA::draw_string(100, 10, "CLint:", BLUE);
|
||||||
|
VGA::draw_u64(150, 10, clocks, BLUE, BLACK);
|
||||||
|
VGA::draw_string(100, 23, "(s)", BLUE);
|
||||||
|
VGA::draw_u64(150, 23, seconds, BLUE, BLACK);
|
||||||
|
|
||||||
for i in 0..4
|
for i in 0..4
|
||||||
{
|
{
|
||||||
VGA::draw_char(10 + i * 16, 46, 'B', RED);
|
VGA::draw_char(10 + i * 16, 46, 'B', RED);
|
||||||
|
|||||||
@@ -15,41 +15,32 @@ class CLint extends Module {
|
|||||||
val MTIMER_ADDR = 0xbff8
|
val MTIMER_ADDR = 0xbff8
|
||||||
|
|
||||||
// Sur le rv32i le timer est constitué de 2 registres pour faire 64 bits
|
// Sur le rv32i le timer est constitué de 2 registres pour faire 64 bits
|
||||||
val mtime_lo = RegInit(0.U(32.W))
|
val mtime = RegInit(0.U(64.W))
|
||||||
val mtime_hi = RegInit(0.U(32.W))
|
|
||||||
|
|
||||||
// Free running, comme on dit chez nous !
|
// Free running, comme on dit chez nous !
|
||||||
mtime_lo := mtime_lo + 1.U
|
mtime := mtime + 1.U
|
||||||
mtime_hi := Mux(mtime_lo + 1.U === 0.U, mtime_hi + 1.U, mtime_hi)
|
|
||||||
|
|
||||||
// La comparaison nécessite également 2 registres, pour une
|
// La comparaison nécessite également 2 registres, pour une
|
||||||
// comparaison sur 64 bits si nécessaire
|
// comparaison sur 64 bits si nécessaire
|
||||||
val mtimecmp_lo = RegInit(0.U(32.W))
|
val mtimecmp = RegInit(0.U(64.W))
|
||||||
val mtimecmp_hi = RegInit(0.U(32.W))
|
|
||||||
// Sortie mtimer interrupt pending dont on se moque pour l'instant
|
// Sortie mtimer interrupt pending dont on se moque pour l'instant
|
||||||
io.tip := (mtime_hi > mtimecmp_hi) || ((mtime_hi === mtimecmp_hi) && (mtime_lo >= mtimecmp_lo))
|
io.tip := (mtime > mtimecmp)
|
||||||
// Valeur par défaut sur le bus de lecture
|
// Valeur par défaut sur le bus de lecture
|
||||||
// avec toujours un cycle de latence
|
// avec toujours un cycle de latence
|
||||||
val clintRegValue = RegInit(0.U(32.W))
|
val clintRegValue = RegInit(0.U(64.W))
|
||||||
|
|
||||||
io.bus.rdata := clintRegValue
|
io.bus.rdata := clintRegValue
|
||||||
|
|
||||||
when(io.bus.en === true.B) {
|
when(io.bus.en === true.B) {
|
||||||
when(io.bus.be.asUInt.orR) { // Écriture
|
when(io.bus.be.asUInt.orR) { // Écriture
|
||||||
when(io.bus.addr === MTIMERCMP_ADDR.U) {
|
when(io.bus.addr === MTIMERCMP_ADDR.U) {
|
||||||
mtimecmp_lo := io.bus.wdata
|
mtimecmp := io.bus.wdata
|
||||||
}.elsewhen(io.bus.addr === (MTIMERCMP_ADDR + 4).U) {
|
|
||||||
mtimecmp_hi := io.bus.wdata
|
|
||||||
}
|
}
|
||||||
}.otherwise { // Lecture
|
}.otherwise { // Lecture
|
||||||
when(io.bus.addr === MTIMER_ADDR.U) {
|
when(io.bus.addr === MTIMER_ADDR.U) {
|
||||||
clintRegValue := mtime_lo
|
clintRegValue := mtime
|
||||||
}.elsewhen(io.bus.addr === (MTIMER_ADDR + 4).U) {
|
|
||||||
clintRegValue := mtime_hi
|
|
||||||
}.elsewhen(io.bus.addr === MTIMERCMP_ADDR.U) {
|
}.elsewhen(io.bus.addr === MTIMERCMP_ADDR.U) {
|
||||||
clintRegValue := mtimecmp_lo
|
clintRegValue := mtimecmp
|
||||||
}.elsewhen(io.bus.addr === (MTIMERCMP_ADDR + 4).U) {
|
|
||||||
clintRegValue := mtimecmp_hi
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user