rust_hdl_widgets/sdram/
cmd.rs

1use rust_hdl_core::prelude::*;
2
3#[derive(Copy, Clone, PartialEq, Debug, LogicState)]
4pub enum SDRAMCommand {
5    LoadModeRegister, // LLL
6    AutoRefresh,      // LLH
7    Precharge,        // LHL
8    BurstTerminate,   // HHL
9    Write,            // HLL
10    Read,             // HLH
11    Active,           // LHH
12    NOP,              // HHH
13}
14
15#[derive(LogicBlock, Default)]
16pub struct SDRAMCommandEncoder {
17    pub ras_not: Signal<Out, Bit>,
18    pub cas_not: Signal<Out, Bit>,
19    pub we_not: Signal<Out, Bit>,
20    pub cs_not: Signal<Out, Bit>,
21    pub cmd: Signal<In, SDRAMCommand>,
22}
23
24impl Logic for SDRAMCommandEncoder {
25    #[hdl_gen]
26    fn update(&mut self) {
27        self.cs_not.next = false;
28        match self.cmd.val() {
29            SDRAMCommand::LoadModeRegister => {
30                self.ras_not.next = false;
31                self.cas_not.next = false;
32                self.we_not.next = false;
33            }
34            SDRAMCommand::AutoRefresh => {
35                self.ras_not.next = false;
36                self.cas_not.next = false;
37                self.we_not.next = true;
38            }
39            SDRAMCommand::Precharge => {
40                self.ras_not.next = false;
41                self.cas_not.next = true;
42                self.we_not.next = false;
43            }
44            SDRAMCommand::BurstTerminate => {
45                self.ras_not.next = true;
46                self.cas_not.next = true;
47                self.we_not.next = false;
48            }
49            SDRAMCommand::Write => {
50                self.ras_not.next = true;
51                self.cas_not.next = false;
52                self.we_not.next = false;
53            }
54            SDRAMCommand::Read => {
55                self.ras_not.next = true;
56                self.cas_not.next = false;
57                self.we_not.next = true;
58            }
59            SDRAMCommand::Active => {
60                self.ras_not.next = false;
61                self.cas_not.next = true;
62                self.we_not.next = true;
63            }
64            SDRAMCommand::NOP => {
65                self.ras_not.next = true;
66                self.cas_not.next = true;
67                self.we_not.next = true;
68            }
69            _ => {}
70        }
71    }
72}
73
74#[derive(LogicBlock, Default)]
75pub struct SDRAMCommandDecoder {
76    pub ras_not: Signal<In, Bit>,
77    pub cas_not: Signal<In, Bit>,
78    pub we_not: Signal<In, Bit>,
79    pub cs_not: Signal<In, Bit>,
80    pub cmd: Signal<Out, SDRAMCommand>,
81}
82
83impl Logic for SDRAMCommandDecoder {
84    #[hdl_gen]
85    fn update(&mut self) {
86        self.cmd.next = SDRAMCommand::NOP;
87        // Decode the SDRAM command
88        if !self.cs_not.val() {
89            if self.ras_not.val() & self.cas_not.val() & self.we_not.val() {
90                self.cmd.next = SDRAMCommand::NOP;
91            } else if self.ras_not.val() & self.cas_not.val() & !self.we_not.val() {
92                self.cmd.next = SDRAMCommand::BurstTerminate;
93            } else if self.ras_not.val() & !self.cas_not.val() & self.we_not.val() {
94                self.cmd.next = SDRAMCommand::Read;
95            } else if self.ras_not.val() & !self.cas_not.val() & !self.we_not.val() {
96                self.cmd.next = SDRAMCommand::Write;
97            } else if !self.ras_not.val() & self.cas_not.val() & self.we_not.val() {
98                self.cmd.next = SDRAMCommand::Active;
99            } else if !self.ras_not.val() & self.cas_not.val() & !self.we_not.val() {
100                self.cmd.next = SDRAMCommand::Precharge;
101            } else if !self.ras_not.val() & !self.cas_not.val() & self.we_not.val() {
102                self.cmd.next = SDRAMCommand::AutoRefresh;
103            } else if !self.ras_not.val() & !self.cas_not.val() & !self.we_not.val() {
104                self.cmd.next = SDRAMCommand::LoadModeRegister;
105            }
106        }
107    }
108}