„SPI_FRAM_Module.sv“ löschen
This commit is contained in:
parent
08300af99a
commit
667101d7fd
@ -1,180 +0,0 @@
|
||||
module SPI_FRAM_Module(
|
||||
input wire SI,
|
||||
output wire SO,
|
||||
input reg SCK,
|
||||
input reg nCS,
|
||||
output reg [7:0] opcode, //contains the command which controls the FRAM
|
||||
output reg [23:0] addr, //contains current address that the memory is reading/writing
|
||||
reg [7:0] mem_data [1023:0], //contains the memory data
|
||||
reg [7:0] stat_reg, //stat_reg Bit 0 is 1 while waking up from Hibernate
|
||||
reg hibernate); //if true, memory is in hibernation
|
||||
|
||||
reg [2:0] bitcnt_rcv; //counts the bits of the current byte when reading from SPI
|
||||
reg [2:0] bitcnt_snd; //counts sent bits for the current sent byte when writing to SPI
|
||||
reg [2:0] bitcnt_mem_write; //counts bits written to memory for the current received byte
|
||||
reg byte_received; //gets high when a full byte is received
|
||||
reg [7:0] byte_data_received; //contains the data of last received byte
|
||||
reg [3:0] byte_count; //counts the bytes of one message; is reset when a new message starts
|
||||
reg [7:0] byte_data_sent; //contains the sent byte after transmission
|
||||
reg send_data; //is set by opcode commands Read status register and Read memory when writing to SPI
|
||||
reg write_to_memory; ////is set by opcode WRITE, when high, incoming Bits from SI are written to the memory at a specific address.
|
||||
integer i; //countdown variable for status register read
|
||||
|
||||
|
||||
initial begin //values are set to startup values of FRAM
|
||||
opcode = 8'h00;
|
||||
stat_reg = 8'b00100000;
|
||||
addr = 24'h000000;
|
||||
byte_count = 4'b0000;
|
||||
byte_data_sent = 8'h00;
|
||||
bitcnt_rcv = 3'b000;
|
||||
bitcnt_snd = 3'b111;
|
||||
bitcnt_mem_write = 3'b111;
|
||||
byte_received = 1'b0;
|
||||
byte_data_received = 8'b00000000;
|
||||
send_data = 0;
|
||||
write_to_memory = 0;
|
||||
i = 8;
|
||||
hibernate = 0;
|
||||
$readmemh("memory.txt", mem_data); //initializes the memory with the contents of memory.txt
|
||||
end
|
||||
|
||||
//receive incoming Bits and organize them bytewise
|
||||
always @(posedge SCK) begin
|
||||
if (bitcnt_rcv == 3'b111) begin
|
||||
byte_count <= byte_count + 4'b0001;
|
||||
end
|
||||
bitcnt_rcv <= bitcnt_rcv + 3'b001;
|
||||
byte_data_received <= {byte_data_received[6:0], SI};
|
||||
|
||||
//when opcode WRÍTE is executed, the incoming bytes are written to memory
|
||||
if (write_to_memory == 1 && nCS == 0) begin
|
||||
mem_data[addr][bitcnt_mem_write+3'b001] = byte_data_received[0];
|
||||
|
||||
if(bitcnt_mem_write == 3'b000) begin
|
||||
addr <= addr + 1;
|
||||
bitcnt_mem_write <= 3'b111;
|
||||
end
|
||||
bitcnt_mem_write <= bitcnt_mem_write - 1;
|
||||
end
|
||||
end
|
||||
always @(posedge SCK) byte_received <= (nCS == 0) && (bitcnt_rcv==3'b111);
|
||||
|
||||
//TRANSMISSION
|
||||
//Read out memory and write to SPI, starts at addr
|
||||
always @(negedge SCK) begin
|
||||
if(send_data == 1 && nCS == 0)
|
||||
begin
|
||||
byte_data_sent <= {byte_data_sent[6:0], mem_data[addr][bitcnt_snd]};
|
||||
bitcnt_snd <= bitcnt_snd - 1;
|
||||
if (bitcnt_snd == 3'b000) begin
|
||||
addr <= addr + 1;
|
||||
bitcnt_snd <= 3'b111;
|
||||
end
|
||||
end
|
||||
//write status register to SO when opcode RDSR is sent
|
||||
else if (opcode == 8'h05 && nCS == 0 && i > 0) begin
|
||||
byte_data_sent <= {byte_data_sent[6:0], stat_reg[i-1]};
|
||||
i = i - 1;
|
||||
end
|
||||
end
|
||||
assign SO = byte_data_sent[0]; // MSB of the transmission is the lsb of byte_data_sent
|
||||
|
||||
|
||||
|
||||
//the following block resets counters when a message has finished
|
||||
always @ (posedge nCS) begin
|
||||
if (opcode == 8'h06) begin //When WLEN opcode is executed, nCS needs to be reset.
|
||||
//Since the message is not finished, no counters should be reset when executing WLEN
|
||||
end
|
||||
else if (opcode == 8'hb9 && nCS == 1) hibernate = 1; //When hibernation opcode 8'hb9 is sent, the device goes into hibernation
|
||||
else begin
|
||||
byte_count = 8'h00;
|
||||
bitcnt_rcv = 3'b000;
|
||||
bitcnt_snd = 3'b111;
|
||||
bitcnt_mem_write = 3'b111;
|
||||
byte_data_received = 8'h00;
|
||||
end
|
||||
send_data = 0; //disables sending data
|
||||
write_to_memory = 0; // disables writing to memory
|
||||
stat_reg[1] = 0; //reset WEL when writing to memory has finished
|
||||
end
|
||||
|
||||
//reset hibernate
|
||||
always @ (negedge nCS) hibernate = 0;
|
||||
//when a byte is received the FRAM-model reacts dependent on the number of bytes received in the current nCS low state, i. e. in one message.
|
||||
|
||||
always @ (posedge byte_received) begin
|
||||
case (byte_count)
|
||||
//Byte 1 of message
|
||||
4'h1: begin //counting starts at 1, not 0.
|
||||
case (byte_data_received)
|
||||
8'h03: //READ Op-code
|
||||
opcode = 8'h03;
|
||||
8'h06: begin //WREN Op-Code
|
||||
opcode = 8'h06;
|
||||
#25; //wait one clock for nCS to get low
|
||||
if (nCS == 1) stat_reg [1] = 1; //Set WEL Bit in Status Register after one clock cycle
|
||||
end
|
||||
//READ STATUS REGISTER Op-Code
|
||||
8'h05: opcode = 8'h05;
|
||||
//HIBERNATE Op-Code
|
||||
8'hb9: begin
|
||||
opcode = 8'hb9;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
//Byte 2 of message
|
||||
4'h2: begin
|
||||
case (byte_data_received)
|
||||
//WRITE
|
||||
8'h02: //WRITE Op-code, only if WREN op-code was executed, WRITE Op-code is permitted.
|
||||
if (opcode == 8'h06) opcode = 8'h02;
|
||||
default:
|
||||
//READ - get highest address byte
|
||||
if (opcode == 8'h03) //upper four bits are not used and are always 0
|
||||
//the address is shifted in from right to left. Byte_data_received is the highest byte of the address
|
||||
addr <= {4'b0000, 12'h000, byte_data_received};
|
||||
endcase
|
||||
end
|
||||
//Byte 3 of message
|
||||
4'h3: begin
|
||||
case (byte_data_received)
|
||||
default:
|
||||
//READ - get middle address byte
|
||||
if (opcode == 8'h03) //if opcode is read, the byte_data_received
|
||||
//is the next byte of the address, followed by 1 byte
|
||||
addr <= {4'b0000, 4'b0000, addr[7:0], byte_data_received};
|
||||
//WRITE - get highest address byte
|
||||
else if (opcode == 8'h02 && stat_reg[1] == 1'b1)
|
||||
addr <= {4'b0000, 12'h000, byte_data_received};
|
||||
endcase
|
||||
end
|
||||
//Byte 4 of message
|
||||
4'h4: begin
|
||||
case (byte_data_received)
|
||||
default:
|
||||
//READ - get the lowest byte of the address
|
||||
if (opcode == 8'h03) begin
|
||||
addr <= {addr[15:0], byte_data_received};
|
||||
send_data = 1; //sets the flag which starts sending every bit out of SO at memory address "addr".
|
||||
end
|
||||
//WRITE - get middle address byte
|
||||
else if (opcode == 8'h02 && stat_reg[1] == 1'b1)
|
||||
addr <= {4'b000, 4'b0000, addr[7:0], byte_data_received};
|
||||
endcase
|
||||
end
|
||||
//Byte 5 of message
|
||||
4'h5: begin
|
||||
case (byte_data_received)
|
||||
default:
|
||||
//WRITE - get lowest address byte and enable write_to_memory, the following bytes are data.
|
||||
if (opcode == 8'h02 && stat_reg[1] == 1'b1) begin
|
||||
addr <= {addr[15:0], byte_data_received};
|
||||
write_to_memory = 1; //set write to memory and wait one clock
|
||||
end
|
||||
endcase
|
||||
end
|
||||
endcase
|
||||
end
|
||||
endmodule
|
Loading…
x
Reference in New Issue
Block a user