283 lines
12 KiB
Verilog
283 lines
12 KiB
Verilog
// Address are in decimal
|
|
// value of memory in hex
|
|
//
|
|
//
|
|
module com_to_mem_FSM#( parameter
|
|
ADDR_WIDTH = 17,
|
|
DATA_WIDTH = 12,
|
|
DEPTH = 76_800,
|
|
SIZE = 4 // size for for registers FSM
|
|
)(
|
|
input clk,
|
|
input i_enable,
|
|
input [7:0] din,
|
|
input TX_Done,
|
|
input i_RX_DV,
|
|
output [3:0] o_state,
|
|
output [3:0] o_byte,
|
|
output [ADDR_WIDTH-1:0] addr_wr,
|
|
output [ADDR_WIDTH-1:0] addr_rd,
|
|
output [DATA_WIDTH-1:0] data_wr,
|
|
output write,
|
|
// output for writing to register memory
|
|
output [6:0] o_addr_wr_reg,
|
|
output [24:0] o_data_reg,
|
|
output o_we_reg
|
|
|
|
);
|
|
|
|
//-------------Internal Constants---------------------------
|
|
localparam [SIZE-1:0] IDLE = 'h0,
|
|
GET_ADDR_W = 'h1,
|
|
GET_VALUE_W = 'h2,
|
|
WRITE_MEM = 'h3,
|
|
GET_ADDR_R = 'h4,
|
|
READ_MEM = 'h5,
|
|
GET_ADDR_W_REG = 'h6,
|
|
GET_VALUE_W_REG = 'h7,
|
|
WRITE_MEM_REG = 'h8;
|
|
|
|
reg [SIZE-1:0] r_state=IDLE,
|
|
r_next=IDLE;
|
|
reg [2:0] r_addr_byte = 3'h0;
|
|
reg [2:0] r_value_byte = 3'h0;
|
|
reg r_RX_DV = 1'b0;
|
|
reg r_RX_DV_OLD = 1'b0;
|
|
reg r_RX_DV_done = 1'b0;
|
|
// reg for main memory
|
|
reg [ADDR_WIDTH-1:0] r_addr_wr = 'b0;
|
|
reg [ADDR_WIDTH-1:0] r_addr_rd = 'b0;
|
|
reg [DATA_WIDTH-1:0] r_data_wr = 'b0;
|
|
reg r_write = 1'b0;
|
|
// reg for register memory
|
|
reg [6:0] r_addr_wr_reg = 'b0;
|
|
reg [24:0] r_data_reg = 'b0;
|
|
reg r_we_reg = 1'b0;
|
|
|
|
//---------state register sequential always block-----------
|
|
always @(posedge clk ) begin
|
|
if (i_enable) begin
|
|
r_state <= r_next;
|
|
end
|
|
end
|
|
//----next state & outputs, combinational always block------
|
|
|
|
always@(posedge clk) begin
|
|
|
|
if ( r_RX_DV == 0 ) begin
|
|
r_RX_DV <= i_RX_DV;
|
|
end
|
|
|
|
if (r_RX_DV || r_state == READ_MEM || r_state == WRITE_MEM || r_state == WRITE_MEM_REG ) begin
|
|
if (i_enable) begin
|
|
case(r_state)
|
|
IDLE : begin
|
|
if (din==8'h70 && r_RX_DV_OLD == 1'b0 ) // if p
|
|
begin
|
|
r_next <= GET_ADDR_W;
|
|
r_addr_byte <= 'h0;
|
|
r_data_wr <= 'h0;
|
|
r_addr_wr <= 'h0;
|
|
end
|
|
else if (din==8'h72 && r_RX_DV_OLD == 1'b0 ) // if r
|
|
begin
|
|
r_next <= GET_ADDR_R;
|
|
r_addr_byte <= 'h0;
|
|
r_addr_rd <= 'h0;
|
|
end
|
|
else if (din==8'h50 && r_RX_DV_OLD == 1'b0 ) // if P
|
|
begin
|
|
r_next <= GET_ADDR_W_REG;
|
|
r_addr_byte <= 'h0;
|
|
r_addr_wr_reg <= 'h0;
|
|
r_data_reg <= 'h0;
|
|
end
|
|
end
|
|
GET_ADDR_W : begin
|
|
if (r_RX_DV_OLD == 1'b0 &&
|
|
((din >= 8'h30 && din < 8'h3A) || // if 0-9
|
|
(din >= 8'h61 && din <= 8'h66) ) // if a-f
|
|
&& r_addr_byte < 'h4 )
|
|
begin
|
|
if (din >= 8'h30 && din < 8'h3A) begin // if 0-9
|
|
r_addr_wr = r_addr_wr * 'd10 + din - 'h30 ;
|
|
r_addr_byte <= r_addr_byte + 1;
|
|
end
|
|
|
|
end
|
|
else if
|
|
(r_RX_DV_OLD == 1'b0 &&
|
|
((din >= 8'h30 && din < 8'h3A) || // if 0-9
|
|
(din >= 8'h61 && din <= 8'h66) ) // if a-f
|
|
&& r_addr_byte == 'h4)
|
|
begin
|
|
if (din >= 8'h30 && din < 8'h3A) begin // if 0-9
|
|
r_addr_wr = r_addr_wr * 'd10 + din - 'h30 ;
|
|
r_value_byte <= 'b0;
|
|
r_next <= GET_VALUE_W;
|
|
end
|
|
|
|
end
|
|
end
|
|
GET_VALUE_W : begin
|
|
if (r_RX_DV_OLD == 1'b0 &&
|
|
((din >= 8'h30 && din < 8'h3A) || // if 0-9
|
|
(din >= 8'h61 && din <= 8'h66) ) // if a-f
|
|
&& r_value_byte < 'd2 )
|
|
begin
|
|
if (din >= 8'h30 && din < 8'h3A) begin // if 0-9
|
|
r_data_wr = r_data_wr * 'h10 + din - 'h30 ;
|
|
r_value_byte <= r_value_byte + 1;
|
|
end
|
|
else if (din >= 8'h61 && din <= 8'h66) begin // if a-f
|
|
r_data_wr = r_data_wr * 'h10 + din - 'h57 ;
|
|
r_value_byte <= r_value_byte + 1;
|
|
end
|
|
end
|
|
else if
|
|
(r_RX_DV_OLD == 1'b0 &&
|
|
((din >= 8'h30 && din < 8'h3A) || // if 0-9
|
|
(din >= 8'h61 && din <= 8'h66) ) // if a-f
|
|
&& r_value_byte == 'd2)
|
|
begin
|
|
if (din >= 8'h30 && din < 8'h3A) begin // if 0-9
|
|
r_data_wr = r_data_wr * 'h10 + din - 'h30 ;
|
|
r_write <= 1'b1;
|
|
r_next <= WRITE_MEM;
|
|
end
|
|
else if (din >= 8'h61 && din <= 8'h66) begin // if a-f
|
|
r_data_wr = r_data_wr * 'h10 + din - 'h57 ;
|
|
r_write <= 1'b1;
|
|
r_next <= WRITE_MEM;
|
|
end
|
|
end
|
|
end
|
|
WRITE_MEM : begin
|
|
r_write <= 1'b0;
|
|
r_addr_byte <= 0;
|
|
r_value_byte <= 0;
|
|
r_next <= IDLE;
|
|
end
|
|
|
|
GET_ADDR_R : begin
|
|
if (r_RX_DV_OLD == 1'b0 &&
|
|
((din >= 8'h30 && din < 8'h3A) || // if 0-9
|
|
(din >= 8'h61 && din <= 8'h66) ) // if a-f
|
|
&& r_addr_byte < 'h4 )
|
|
begin
|
|
if (din >= 8'h30 && din < 8'h3A) begin // if 0-9
|
|
r_addr_rd = r_addr_rd * 'd10 + din - 'h30 ;
|
|
r_addr_byte <= r_addr_byte + 1;
|
|
end
|
|
|
|
end
|
|
else if
|
|
(r_RX_DV_OLD == 1'b0 &&
|
|
((din >= 8'h30 && din < 8'h3A) || // if 0-9
|
|
(din >= 8'h61 && din <= 8'h66) ) // if a-f
|
|
&& r_addr_byte == 'h4)
|
|
begin
|
|
if (din >= 8'h30 && din < 8'h3A) begin // if 0-9
|
|
r_addr_rd = r_addr_rd * 'd10 + din - 'h30 ;
|
|
r_next <= READ_MEM;
|
|
end
|
|
|
|
end
|
|
end
|
|
|
|
READ_MEM : begin
|
|
r_next <= IDLE;
|
|
r_addr_byte <= 0;
|
|
end
|
|
// wrinting in register memory
|
|
GET_ADDR_W_REG : begin
|
|
if (r_RX_DV_OLD == 1'b0 &&
|
|
((din >= 8'h30 && din < 8'h3A) || // if 0-9
|
|
(din >= 8'h61 && din <= 8'h66) ) // if a-f
|
|
&& r_addr_byte < 'h1 )
|
|
begin
|
|
if (din >= 8'h30 && din < 8'h3A) begin // if 0-9
|
|
r_addr_wr_reg = r_addr_wr_reg * 'h10 + din - 'h30 ;
|
|
r_addr_byte <= r_addr_byte + 1;
|
|
end
|
|
else if (din >= 8'h61 && din <= 8'h66) begin // if a-f
|
|
r_addr_wr_reg = r_addr_wr_reg * 'h10 + din - 'h57 ;
|
|
r_value_byte <= r_value_byte + 1;
|
|
end
|
|
end
|
|
else if
|
|
(r_RX_DV_OLD == 1'b0 &&
|
|
((din >= 8'h30 && din < 8'h3A) || // if 0-9
|
|
(din >= 8'h61 && din <= 8'h66) ) // if a-f
|
|
&& r_addr_byte == 'h1)
|
|
begin
|
|
if (din >= 8'h30 && din < 8'h3A) begin // if 0-9
|
|
r_addr_wr_reg = r_addr_wr_reg * 'h10 + din - 'h30 ;
|
|
r_value_byte <= 'b0;
|
|
r_next <= GET_VALUE_W_REG;
|
|
end
|
|
else if (din >= 8'h61 && din <= 8'h66) begin // if a-f
|
|
r_addr_wr_reg = r_addr_wr_reg * 'h10 + din - 'h57 ;
|
|
r_value_byte <= 'b0;
|
|
r_next <= GET_VALUE_W_REG;
|
|
end
|
|
end
|
|
end
|
|
GET_VALUE_W_REG : begin
|
|
if (r_RX_DV_OLD == 1'b0 &&
|
|
((din >= 8'h30 && din < 8'h3A) || // if 0-9
|
|
(din >= 8'h61 && din <= 8'h66) ) // if a-f
|
|
&& r_value_byte < 'd6 )
|
|
begin
|
|
if (din >= 8'h30 && din < 8'h3A) begin // if 0-9
|
|
r_data_reg = r_data_reg * 'h10 + din - 'h30 ;
|
|
r_value_byte <= r_value_byte + 1;
|
|
end
|
|
else if (din >= 8'h61 && din <= 8'h66) begin // if a-f
|
|
r_data_reg = r_data_reg * 'h10 + din - 'h57 ;
|
|
r_value_byte <= r_value_byte + 1;
|
|
end
|
|
end
|
|
else if
|
|
(r_RX_DV_OLD == 1'b0 &&
|
|
((din >= 8'h30 && din < 8'h3A) || // if 0-9
|
|
(din >= 8'h61 && din <= 8'h66) ) // if a-f
|
|
&& r_value_byte == 'd6)
|
|
begin
|
|
if (din >= 8'h30 && din < 8'h3A) begin // if 0-9
|
|
r_data_reg = r_data_reg * 'h10 + din - 'h30 ;
|
|
r_we_reg <= 1'b1;
|
|
r_next <= WRITE_MEM_REG;
|
|
end
|
|
else if (din >= 8'h61 && din <= 8'h66) begin // if a-f
|
|
r_data_reg = r_data_reg * 'h10 + din - 'h57 ;
|
|
r_we_reg <= 1'b1;
|
|
r_next <= WRITE_MEM_REG;
|
|
end
|
|
end
|
|
end
|
|
WRITE_MEM_REG : begin
|
|
r_we_reg <= 1'b0;
|
|
r_addr_wr_reg <= 1'b0;
|
|
r_value_byte <= 1'b0;
|
|
r_next <= IDLE;
|
|
end
|
|
default: r_next <= IDLE; // on error
|
|
endcase
|
|
r_RX_DV <= 'b0;
|
|
end
|
|
end
|
|
end
|
|
//-------------------- assignning combionational logic----------------------------
|
|
assign write = r_write;
|
|
assign addr_wr = r_addr_wr ;
|
|
assign data_wr = r_data_wr ;
|
|
assign addr_rd = r_addr_rd ;
|
|
assign o_state = r_state;
|
|
assign o_byte = (r_state == 'h1 || r_state == 'h4 ) ? r_addr_byte : r_value_byte;
|
|
|
|
assign o_addr_wr_reg = r_addr_wr_reg;
|
|
assign o_data_reg = r_data_reg;
|
|
assign o_we_reg = r_we_reg;
|
|
|
|
endmodule |