aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Nazaryev <sergey@nazaryev.ru>2015-12-25 22:15:47 +0300
committerSergey Nazaryev <sergey@nazaryev.ru>2015-12-25 22:16:06 +0300
commiteabeba483231b0c6e1fac89c2903169f4e028c9a (patch)
treeff4f7c6210843bde40b45028675bbe74f04e40bf
parente4381701562660b0594f09e9ad4d5f5c5ff66fc5 (diff)
downloadcircuit-design-lab234-eabeba483231b0c6e1fac89c2903169f4e028c9a.zip
circuit-design-lab234-eabeba483231b0c6e1fac89c2903169f4e028c9a.tar.gz
circuit-design-lab234-eabeba483231b0c6e1fac89c2903169f4e028c9a.tar.bz2
it now works
-rw-r--r--rom_ctrl.v225
-rw-r--r--rom_wb.v81
-rw-r--r--romctrl_testbench.v122
-rw-r--r--romwb_testbench.v111
-rw-r--r--testbench.v114
5 files changed, 401 insertions, 252 deletions
diff --git a/rom_ctrl.v b/rom_ctrl.v
index 1957a03..ebc887c 100644
--- a/rom_ctrl.v
+++ b/rom_ctrl.v
@@ -8,45 +8,53 @@ module rom_ctrl(
input [4:0] adr_i,
output reg[31:0] dat_o,
- output busy_o
+ output ack_o
);
-wire buf_i_wr, buf_o_wr, buf_i_rd, buf_o_rd;
-wire buf_i_empty, buf_o_empty, buf_i_full, buf_o_full;
-wire buf_i_rst, buf_o_rst;
-wire[31:0] buf_i_data_i, buf_o_data_i, buf_i_data_o, buf_o_data_o;
+wire read_buf_wr, write_buf_wr, read_buf_rd, write_buf_rd;
+wire read_buf_empty, write_buf_empty, read_buf_full, write_buf_full;
+wire read_buf_rst, write_buf_rst;
+wire[31:0] read_buf_data_i, write_buf_data_i, read_buf_data_o, write_buf_data_o;
-reg[7:0] spi_writer_count;
reg spi_writer_wr;
-wire spi_writer_tx_need, spi_writer_finish;
+wire spi_writer_tx_need;
wire[23:0] spi_writer_addr;
+wire spi_finish;
+
//***********************************
// Controller state
//***********************************
// Memory for storing state
-reg[4:0] state;
+reg[4:0] state = IDLE_S;
+reg[4:0] next_state;
-// Show state of controller for wb
-assign busy_o = ( state == IDLE ? 0 : 1 );
+// ACK
+assign ack_o = ( state == WAIT_S ? 0 : 1 );
// List of states
-localparam IDLE = 4'd0,
- WRITING_DATA = 4'd1,
- READING_DATA = 4'd2,
- WRITING_STATUS = 4'd3,
- READING_STATUS = 4'd4,
- BULK_ERASE = 4'd5,
- ERASING_SECTOR = 4'd6,
- QUICK_OPERATION = 4'd7;
+localparam IDLE_S = 0,
+ WAIT_S = 1,
+ WRITING_DATA_S = 2,
+ READING_DATA_S = 3,
+ WRITING_STATUS_S = 4,
+ READING_STATUS_S = 5,
+ BULK_ERASING_S = 6,
+ ERASING_SECTOR_S = 7,
+ READING_REG_S = 8,
+ WRITING_REG_S = 9,
+ POPPING_READ_BUFFER_S = 10,
+ PUSHING_WRITE_BUFFER_S = 11,
+ CLEARING_READ_BUFFER_S = 12,
+ CLEARING_WRITE_BUFFER_S = 13;
//***********************************
// Virtual registers
//***********************************
// Memory for storing registers
-reg[31:0] registers[8:0];
+reg[31:0] registers[31:0];
// List of virtual registers
localparam WADDR = 0,
@@ -66,29 +74,29 @@ localparam WADDR = 0,
//***********************************
// Empty WRITE BUFFER when write to WADDR
-assign buf_o_rst = ( wr_i && adr_i == WADDR );
+assign write_buf_rst = ( state == CLEARING_WRITE_BUFFER_S );
// Get data for writing from dat_i
-assign buf_o_data_i = dat_i;
+assign write_buf_data_i = dat_i;
// Write to the WRITE BUFFER when write data to WDATA
-assign buf_o_wr = ( wr_i && adr_i == WDATA );
+assign write_buf_wr = ( state == PUSHING_WRITE_BUFFER_S );
// Read data from WRITE BUFFER when write data to SPI controller
-assign buf_o_rd = ( state == WRITING_DATA && spi_writer_tx_need );
+assign write_buf_rd = ( state == WRITING_DATA_S && spi_writer_tx_need );
-fifo buf_o(
+fifo write_buf(
.clk_i(clk_i),
- .rst_i(buf_o_rst),
+ .rst_i(write_buf_rst),
- .wr_i(buf_o_wr),
- .data_i(buf_o_data_i),
+ .wr_i(write_buf_wr),
+ .data_i(write_buf_data_i),
- .rd_i(buf_o_rd),
- .data_o(buf_o_data_o),
+ .rd_i(write_buf_rd),
+ .data_o(write_buf_data_o),
- .empty_o(buf_o_empty),
- .full_o(buf_o_full)
+ .empty_o(write_buf_empty),
+ .full_o(write_buf_full)
);
//***********************************
@@ -96,34 +104,29 @@ fifo buf_o(
//***********************************
// Empty READ BUFFER when write to RADDR
-assign buf_i_rst = ( wr_i && adr_i == RADDR );
+assign read_buf_rst = ( state == CLEARING_READ_BUFFER_S );
// Mark as read top of READ BUFFER when read data from RDATA
-assign buf_i_rd = ( rd_i && adr_i == RDATA );
-
-// Write to READ BUFFER when read data from SPI controller
-//assign buf_i_wr = ( state == READING && spi_writer_tx_need );
-assign buf_i_wr = 1'b0; //FIXME
-// Get data for writing from SPI_DATA_I
-assign buf_i_data_i = 1'b0; //FIXME
+assign read_buf_rd = ( state == POPPING_READ_BUFFER_S );
-fifo buf_i(
+fifo read_buf(
.clk_i(clk_i),
- .rst_i(buf_i_rst),
- .rd_i(buf_i_rd),
- .wr_i(buf_i_wr),
- .empty_o(buf_i_empty),
- .full_o(buf_i_full),
- .data_i(buf_i_data_i),
- .data_o(buf_i_data_o)
+ .rst_i(read_buf_rst),
+ .rd_i(read_buf_rd),
+ .wr_i(read_buf_wr),
+ .empty_o(read_buf_empty),
+ .full_o(read_buf_full),
+ .data_i(read_buf_data_i),
+ .data_o(read_buf_data_o)
);
//***********************************
-// SPI Core
+// M25P16 SPI Writer Core
//***********************************
-assign spi_writer_tx = buf_o_data_o;
+assign spi_writer_tx = write_buf_data_o;
assign spi_writer_addr = registers[WADDR][23:0];
+
/*
spi_writer spi_writer(
.clk_i(clk_i),
@@ -131,52 +134,114 @@ spi_writer spi_writer(
.adr_i(spi_writer_addr),
.wr_i(spi_writer_wr),
.tx_need(spi_writer_tx_need),
- .finish_o(spi_writer_finish)
+ .finish_o(spi_finish),
+
+ .spi_mosi()
+ .spi_miso()
);*/
-always @(posedge clk_i, posedge rst_i)
- if( state == IDLE )
- if( wr_i )
- registers[adr_i] <= dat_i;
- else if( rd_i )
- dat_o <= registers[adr_i];
+//***********************************
+// M25P16 SPI Reader Core
+//***********************************
+
+assign spi_writer_tx = write_buf_data_o;
+assign spi_writer_addr = registers[WADDR][23:0];
+
+/*
+spi_reader spi_reader(
+ .clk_i(clk_i),
+ .tx_i(spi_writer_tx),
+ .adr_i(spi_writer_addr),
+ .wr_i(spi_writer_wr),
+ .dat_o(read_buf_wr)
+ .dat_valid(
+ .finish_o(spi_finish)
+
+ .spi_mosi()
+ .spi_miso()
+);*/
+
+//***********************************
+// Virtual Registers I/O
+//***********************************
+
+always @( posedge clk_i )
+ if( state == READING_REG_S )
+ dat_o <= registers[adr_i];
+
+always @( posedge clk_i )
+ if( state == WRITING_REG_S ||
+ adr_i == RADDR ||
+ adr_i == WADDR )
+ registers[adr_i] <= dat_i;
-always @(posedge clk_i, posedge rst_i)
+//***********************************
+// Rom Controller FSM
+//***********************************
+
+always @( posedge clk_i, posedge rst_i )
if( rst_i )
- state <= IDLE;
+ state <= IDLE_S;
else
state <= next_state;
always @*
begin
next_state = state;
- case( state ):
- IDLE:
+ case( state )
+ IDLE_S:
begin
- case(adr_i)
- RLEN:
- next_state = READING_DATA;
- WLEN:
- next_state = WRITING_DATA;
- SEC_ADDR_ERASE:
- next_state = ERASING_SECTOR;
- STATUS:
- next_state = ( rd_i ? READING_STATUS : WRITING_STATUS );
- default:
- next_state = QUICK_OPERATION;
- endcase
+ if( adr_i == RLEN && wr_i )
+ next_state = READING_DATA_S;
+
+ else if( adr_i == RADDR && wr_i )
+ next_state = CLEARING_READ_BUFFER_S;
+
+ else if( adr_i == RDATA && wr_i )
+ next_state = POPPING_READ_BUFFER_S;
+
+
+ else if( adr_i == WDATA && wr_i )
+ next_state = PUSHING_WRITE_BUFFER_S;
+
+ else if( adr_i == WADDR && wr_i )
+ next_state = CLEARING_WRITE_BUFFER_S;
+
+ else if( adr_i == WLEN && wr_i)
+ next_state = WRITING_DATA_S;
+
+
+ else if( wr_i && adr_i == SEC_ADDR_ERASE )
+ next_state = ERASING_SECTOR_S;
+
+ else if( wr_i && adr_i == BULK_ERASE )
+ next_state = BULK_ERASING_S;
+
+ else if( rd_i && adr_i == STATUS )
+ next_state = READING_STATUS_S;
+
+ else if( wr_i && adr_i == STATUS )
+ next_state = WRITING_STATUS_S;
+
+
+ else if( wr_i )
+ next_state = WRITING_REG_S;
+
+ else if( rd_i )
+ next_state = READING_REG_S;
end
- WRITING_DATA:
- if( spi_writer_finish )
- next_state = IDLE;
+ ERASING_SECTOR_S, BULK_ERASING_S, READING_STATUS_S, WRITING_STATUS_S, READING_DATA_S, WRITING_DATA_S:
+ if( spi_finish )
+ next_state = WAIT_S;
+
+ POPPING_READ_BUFFER_S, CLEARING_READ_BUFFER_S, CLEARING_WRITE_BUFFER_S, PUSHING_WRITE_BUFFER_S, READING_REG_S, WRITING_REG_S:
+ next_state = WAIT_S;
- QUICK_OPERATION:
- next_state = IDLE;
+ WAIT_S:
+ next_state = IDLE_S;
- default:
- next_state = state;
- endcase
+ endcase
end
endmodule
diff --git a/rom_wb.v b/rom_wb.v
index 3e52409..c0b6c6c 100644
--- a/rom_wb.v
+++ b/rom_wb.v
@@ -3,65 +3,28 @@ module rom_wb (
input wb_clk_i,
input wb_rst_i,
input [31:0] wb_dat_i,
- input [31:0] wb_adr_i,
+ input [4:0] wb_adr_i,
input wb_we_i,
input [3:0] wb_sel_i,
input wb_cyc_i,
input wb_stb_i,
- output reg [31:0] wb_dat_o,
- output reg wb_ack_o
-);
-
-localparam BUSY = 1,
- IDLE = 0;
-
-reg old_state = 1'b0;
-wire new_state;
-
-wb_conv wb_conv(
- .wb_clk_i ( wb_clk_i ),
- .wb_rst_i ( wb_rst_i ),
- .wb_dat_i ( wb_dat_i ),
- .wb_adr_i ( wb_adr_i ),
- .wb_we_i ( wb_we_i ),
- .wb_sel_i ( wb_sel_i ),
- .wb_cyc_i ( wb_cyc_i ),
- .wb_stb_i ( wb_stb_i ),
-
- .wb_dat_o ( wb_dat_o ),
- .wb_ack_o ( wb_ack_o ),
-
- .data_
- .addr_
- .wr_en
- .rd_en
- .busy
- .data_
-);
-
-spi_conv spi_conv(
- .mosi
- .miso
- .clk
- .ss
-
- .data_
- .addr_
- .wr_en
- .rd_en
- .busy
- .data_
+ output [31:0] wb_dat_o,
+ output wb_ack_o
);
+reg ack_d1 = 1'b0;
+wire ack_w;
+wire[4:0] rom_addr_i;
+wire[31:0] rom_dat_i, rom_dat_o;
+wire rom_clk_i, rom_read_i, rom_write_i;
assign rom_read_i = wb_cyc_i & wb_stb_i & !wb_we_i;
assign rom_write_i = wb_cyc_i & wb_stb_i & wb_we_i;
assign rom_dat_i = wb_dat_i;
-assign rom_dat_o = wb_dat_o;
assign rom_addr_i = wb_adr_i;
-assign rom_clk_i = wb_adr_i;
+assign rom_clk_i = wb_clk_i;
rom_ctrl rom_ctrl(
.clk_i(rom_clk_i),
@@ -75,17 +38,19 @@ rom_ctrl rom_ctrl(
.wr_i(rom_write_i),
.dat_i(rom_dat_i),
- .busy_o(new_state)
+ .ack_o(ack_w)
);
-always @(posedge clk_i)
-begin
- // если был занят, а стал свободен, значит контроллер завершил операцию и
- // нужно дёрнуть один раз ACK_O и положить на следующем такте, чтобы wishbone
- // master оповестился о конце операции slave'а
-
- ack_o <= ( old_state == BUSY && new_state == IDLE ? 1 : 0);
- old_state <= new_state;
-end
-
-endmodule
+always @(posedge wb_clk_i, posedge wb_rst_i )
+ if( wb_rst_i )
+ ack_d1 <= 0;
+ else
+ ack_d1 <= ack_w;
+
+// если контроллер был занят, а стал свободен, значит контроллер завершил операцию и
+// нужно дёрнуть один раз ACK_O и положить на следующем такте, чтобы wishbone
+// master оповестился о конце операции slave'а
+assign wb_ack_o = ( ack_d1 ) && ( !ack_w );
+assign wb_dat_o = rom_dat_o;
+
+endmodule \ No newline at end of file
diff --git a/romctrl_testbench.v b/romctrl_testbench.v
new file mode 100644
index 0000000..9c4b1cf
--- /dev/null
+++ b/romctrl_testbench.v
@@ -0,0 +1,122 @@
+`timescale 1ns / 1ps
+
+////////////////////////////////////////////////////////////////////////////////
+// Company:
+// Engineer:
+//
+// Create Date: 13:56:22 12/25/2015
+// Design Name: rom_ctrl
+// Module Name: /home/sn/src/circuit-design-lab234//romctrl-testbench.v
+// Project Name: m25p16
+// Target Device:
+// Tool versions:
+// Description:
+//
+// Verilog Test Fixture created by ISE for module: rom_ctrl
+//
+// Dependencies:
+//
+// Revision:
+// Revision 0.01 - File Created
+// Additional Comments:
+//
+////////////////////////////////////////////////////////////////////////////////
+
+module romctrl_testbench;
+
+ // Inputs
+ reg clk_i;
+ reg rst_i;
+ reg rd_i;
+ reg wr_i;
+ reg [31:0] dat_i;
+ reg [4:0] adr_i;
+
+ // Outputs
+ wire [31:0] dat_o;
+ wire ack_o;
+
+ // Instantiate the Unit Under Test (UUT)
+ rom_ctrl uut (
+ .clk_i(clk_i),
+ .rst_i(rst_i),
+ .rd_i(rd_i),
+ .wr_i(wr_i),
+ .dat_i(dat_i),
+ .adr_i(adr_i),
+ .dat_o(dat_o),
+ .ack_o(ack_o)
+ );
+
+initial begin
+ clk_i = 0;
+ forever begin
+ clk_i = !clk_i;
+ #50;
+ end
+end
+
+reg [31:0] read_value;
+initial begin
+ rst_i = 0;
+
+ clear();
+
+ $display("hello world");
+
+ write( 5'hF, 32'haabbccdd );
+ read( 5'hF, read_value );
+
+ $display("read_value = 0x%h", read_value);
+
+ clear();
+
+ $finish();
+end
+
+task write( input [4:0] adr, input [31:0] dat );
+begin
+ @( posedge clk_i );
+
+ adr_i <= adr;
+ dat_i <= dat;
+ wr_i <= 1;
+ rd_i <= 0;
+
+ @( posedge clk_i );
+ while( ack_o == 1'b1 )
+ @( posedge clk_i );
+
+ wr_i <= 0;
+ rd_i <= 0;
+end
+endtask
+
+task read( input [4:0] adr, output [31:0] dat );
+begin
+ adr_i <= adr;
+ wr_i <= 0;
+ rd_i <= 1;
+
+ @( posedge clk_i );
+ while( ack_o == 1'b1 )
+ @( posedge clk_i );
+
+ dat = dat_o;
+ wr_i <= 0;
+ rd_i <= 0;
+end
+endtask
+
+task clear();
+begin
+ @( posedge clk_i );
+ rd_i <= 0;
+ wr_i <= 0;
+ dat_i <= 0;
+ adr_i <= 0;
+end
+endtask
+
+endmodule
+
diff --git a/romwb_testbench.v b/romwb_testbench.v
new file mode 100644
index 0000000..926d449
--- /dev/null
+++ b/romwb_testbench.v
@@ -0,0 +1,111 @@
+`timescale 1ns / 1ps
+
+module romwb_testbench;
+
+reg wb_clk_i;
+reg wb_rst_i;
+reg [31:0] wb_dat_i;
+reg [31:0] wb_adr_i;
+reg wb_we_i;
+reg [3:0] wb_sel_i;
+reg wb_cyc_i;
+reg wb_stb_i;
+
+wire [31:0] wb_dat_o;
+wire wb_ack_o;
+
+rom_wb uut (
+ .wb_clk_i(wb_clk_i),
+ .wb_rst_i(wb_rst_i),
+ .wb_dat_i(wb_dat_i),
+ .wb_adr_i(wb_adr_i),
+ .wb_we_i(wb_we_i),
+ .wb_sel_i(wb_sel_i),
+ .wb_cyc_i(wb_cyc_i),
+ .wb_stb_i(wb_stb_i),
+ .wb_dat_o(wb_dat_o),
+ .wb_ack_o(wb_ack_o)
+);
+
+initial begin
+ wb_clk_i = 0;
+ forever begin
+ wb_clk_i = !wb_clk_i;
+ #50;
+ end
+end
+
+reg [31:0] read_value;
+initial begin
+ wb_sel_i = 0;
+ wb_rst_i = 0;
+
+ clear();
+
+ $display("hello world");
+
+ write( 5'h4, 32'haabbccdd );
+ read( 5'h4, read_value );
+
+ $display("read_value = 0x%h", read_value);
+
+ clear();
+
+ $finish();
+end
+
+task write( input [4:0] adr, input [31:0] dat );
+begin
+ @( posedge wb_clk_i );
+
+ wb_adr_i <= adr; // master set ADR to 4 for WRITING to ADR
+ wb_we_i <= 1; // master set WE_I to 1 for WRITING
+ wb_stb_i <= 1; // master set STB_O to 1 for indicate of start phase
+ wb_cyc_i <= 1; // master set CYC_O to 1 for indicate of start cycle
+ wb_dat_i <= dat;
+
+ @( posedge wb_clk_i );
+ while( wb_ack_o == 1'b0 )
+ @( posedge wb_clk_i );
+
+ wb_stb_i <= 1'b0;
+ wb_cyc_i <= 1'b0;
+end
+endtask
+
+task read( input [4:0] adr, output [31:0] dat );
+begin
+ @( posedge wb_clk_i );
+
+ wb_adr_i <= adr; // master set ADR to 4 for READING from ADR
+ wb_we_i <= 0; // master set WE_I to 0 for READING
+ wb_stb_i <= 1; // master set STB_O to 1 for indicate of start phase
+ wb_cyc_i <= 1; // master set CYC_O to 1 for indicate of start cycle
+
+ @( posedge wb_clk_i );
+ while( wb_ack_o == 1'b0 )
+ @( posedge wb_clk_i );
+
+ dat <= wb_dat_o;
+
+ wb_stb_i <= 1'b0;
+ wb_cyc_i <= 1'b0;
+end
+endtask
+
+task clear();
+begin
+ @( posedge wb_clk_i );
+
+ wb_adr_i <= 0;
+ wb_we_i <= 0;
+ wb_stb_i <= 0;
+ wb_cyc_i <= 0;
+ wb_sel_i = 0;
+ wb_rst_i = 0;
+end
+endtask
+
+endmodule
+
+
diff --git a/testbench.v b/testbench.v
deleted file mode 100644
index 5e683a5..0000000
--- a/testbench.v
+++ /dev/null
@@ -1,114 +0,0 @@
-`timescale 1ns / 1ps
-
-////////////////////////////////////////////////////////////////////////////////
-// Company:
-// Engineer:
-//
-// Create Date: 03:00:40 12/10/2015
-// Design Name: fifo
-// Module Name: C:/Users/M25P16/ff.v
-// Project Name: M25P16
-// Target Device:
-// Tool versions:
-// Description:
-//
-// Verilog Test Fixture created by ISE for module: fifo
-//
-// Dependencies:
-//
-// Revision:
-// Revision 0.01 - File Created
-// Additional Comments:
-//
-////////////////////////////////////////////////////////////////////////////////
-
-module ff;
-
- // Inputs
- reg clk_i;
- reg rst_i;
- reg wr_i;
- reg [31:0] data_i;
- reg rd_i;
-
- // Outputs
- wire full_o;
- wire [31:0] data_o;
- wire empty_o;
-
- // Instantiate the Unit Under Test (UUT)
- fifo uut (
- .clk_i(clk_i),
- .rst_i(rst_i),
- .wr_i(wr_i),
- .data_i(data_i),
- .full_o(full_o),
- .rd_i(rd_i),
- .data_o(data_o),
- .empty_o(empty_o)
- );
-
- initial
- begin
- clk_i = 0;
-
- forever
- #5 clk_i = !clk_i;
- end
-
- initial begin
- // Initialize Inputs
- clk_i = 0;
- rst_i = 0;
- wr_i = 0;
- data_i = 0;
- rd_i = 0;
-
- // Wait 100 ns for global reset to finish
- #100;
- @(posedge clk_i);
-
- // Add stimulus here
-
- wr_i = 1;
- data_i = 32'hAABBCCDD;
-
- @(posedge clk_i);
-
- wr_i = 1;
- data_i = 32'hCCBBCCDD;
-
- @(posedge clk_i);
-
- wr_i = 0;
- rd_i = 1;
-
- @(posedge clk_i);
-
- rd_i = 0;
- #100;
-
- @(posedge clk_i);
- rd_i = 1;
-
- @(posedge clk_i);
- rd_i = 0;
- @(posedge clk_i);
- rd_i = 1;
-
- @(posedge clk_i);
- rd_i = 0;
- @(posedge clk_i);
- rd_i = 1;
-
- @(posedge clk_i);
- rd_i = 0;
- @(posedge clk_i);
- rd_i = 1;
-
- @(posedge clk_i);
- rd_i = 0;
- end
-
-endmodule
-