initial commit
diff --git a/verilog/rtl/simpleuart.v b/verilog/rtl/simpleuart.v
index 50808cb..51e95c7 100644
--- a/verilog/rtl/simpleuart.v
+++ b/verilog/rtl/simpleuart.v
@@ -17,121 +17,180 @@
*
*/
-module simpleuart (
- input clk,
- input resetn,
+module simpleuart_wb # (
+ parameter BASE_ADR = 32'h 2000_0000,
+ parameter CLK_DIV = 8'h00,
+ parameter DATA = 8'h04
+) (
+ input wb_clk_i,
+ input wb_rst_i,
- output ser_tx,
- input ser_rx,
+ input [31:0] wb_adr_i, // (verify): input address was originaly 22 bits , why ? (max number of words ?)
+ input [31:0] wb_dat_i,
+ input [3:0] wb_sel_i,
+ input wb_we_i,
+ input wb_cyc_i,
+ input wb_stb_i,
- input [3:0] reg_div_we,
- input [31:0] reg_div_di,
- output [31:0] reg_div_do,
+ output wb_ack_o,
+ output [31:0] wb_dat_o,
- input reg_dat_we,
- input reg_dat_re,
- input [31:0] reg_dat_di,
- output [31:0] reg_dat_do,
- output reg_dat_wait
+ output ser_tx,
+ input ser_rx
+
);
- reg [31:0] cfg_divider;
+ wire [31:0] simpleuart_reg_div_do;
+ wire [31:0] simpleuart_reg_dat_do;
- reg [3:0] recv_state;
- reg [31:0] recv_divcnt;
- reg [7:0] recv_pattern;
- reg [7:0] recv_buf_data;
- reg recv_buf_valid;
+ wire resetn = ~wb_rst_i;
+ wire valid = wb_stb_i && wb_cyc_i;
+ wire simpleuart_reg_div_sel = valid && (wb_adr_i == (BASE_ADR | CLK_DIV));
+ wire simpleuart_reg_dat_sel = valid && (wb_adr_i == (BASE_ADR | DATA));
- reg [9:0] send_pattern;
- reg [3:0] send_bitcnt;
- reg [31:0] send_divcnt;
- reg send_dummy;
+ wire [3:0] reg_div_we = simpleuart_reg_div_sel ? (wb_sel_i & {4{wb_we_i}}): 4'b 0000; // simpleuart_reg_div_sel ? mem_wstrb : 4'b 0000), // sel: depends on address buss
+ wire reg_dat_we = simpleuart_reg_dat_sel ? (wb_sel_i[0] & wb_we_i): 1'b 0; // simpleuart_reg_dat_sel ? mem_wstrb[0] : 1'b 0
- assign reg_div_do = cfg_divider;
+ wire [31:0] mem_wdata = wb_dat_i;
+ wire reg_dat_re = simpleuart_reg_dat_sel && !wb_sel_i && ~wb_we_i; // read_enable
- assign reg_dat_wait = reg_dat_we && (send_bitcnt || send_dummy);
- assign reg_dat_do = recv_buf_valid ? recv_buf_data : ~0;
+ assign wb_dat_o = simpleuart_reg_div_sel ? simpleuart_reg_div_do: simpleuart_reg_dat_do;
+ assign wb_ack_o = (simpleuart_reg_div_sel || simpleuart_reg_dat_sel) && (!reg_dat_wait);
+
+ simpleuart simpleuart (
+ .clk (wb_clk_i),
+ .resetn (resetn),
- always @(posedge clk) begin
- if (!resetn) begin
- cfg_divider <= 1;
- end else begin
- if (reg_div_we[0]) cfg_divider[ 7: 0] <= reg_div_di[ 7: 0];
- if (reg_div_we[1]) cfg_divider[15: 8] <= reg_div_di[15: 8];
- if (reg_div_we[2]) cfg_divider[23:16] <= reg_div_di[23:16];
- if (reg_div_we[3]) cfg_divider[31:24] <= reg_div_di[31:24];
- end
- end
+ .ser_tx (ser_tx),
+ .ser_rx (ser_rx),
- always @(posedge clk) begin
- if (!resetn) begin
- recv_state <= 0;
- recv_divcnt <= 0;
- recv_pattern <= 0;
- recv_buf_data <= 0;
- recv_buf_valid <= 0;
- end else begin
- recv_divcnt <= recv_divcnt + 1;
- if (reg_dat_re)
- recv_buf_valid <= 0;
- case (recv_state)
- 0: begin
- if (!ser_rx)
- recv_state <= 1;
- recv_divcnt <= 0;
- end
- 1: begin
- if (2*recv_divcnt > cfg_divider) begin
- recv_state <= 2;
- recv_divcnt <= 0;
- end
- end
- 10: begin
- if (recv_divcnt > cfg_divider) begin
- recv_buf_data <= recv_pattern;
- recv_buf_valid <= 1;
- recv_state <= 0;
- end
- end
- default: begin
- if (recv_divcnt > cfg_divider) begin
- recv_pattern <= {ser_rx, recv_pattern[7:1]};
- recv_state <= recv_state + 1;
- recv_divcnt <= 0;
- end
- end
- endcase
- end
- end
+ .reg_div_we (reg_div_we),
+ .reg_div_di (mem_wdata),
+ .reg_div_do (simpleuart_reg_div_do),
- assign ser_tx = send_pattern[0];
+ .reg_dat_we (reg_dat_we),
+ .reg_dat_re (reg_dat_re),
+ .reg_dat_di (mem_wdata),
+ .reg_dat_do (simpleuart_reg_dat_do),
+ .reg_dat_wait(reg_dat_wait)
+ );
- always @(posedge clk) begin
- if (reg_div_we)
- send_dummy <= 1;
- send_divcnt <= send_divcnt + 1;
- if (!resetn) begin
- send_pattern <= ~0;
- send_bitcnt <= 0;
- send_divcnt <= 0;
- send_dummy <= 1;
- end else begin
- if (send_dummy && !send_bitcnt) begin
- send_pattern <= ~0;
- send_bitcnt <= 15;
- send_divcnt <= 0;
- send_dummy <= 0;
- end else
- if (reg_dat_we && !send_bitcnt) begin
- send_pattern <= {1'b1, reg_dat_di[7:0], 1'b0};
- send_bitcnt <= 10;
- send_divcnt <= 0;
- end else
- if (send_divcnt > cfg_divider && send_bitcnt) begin
- send_pattern <= {1'b1, send_pattern[9:1]};
- send_bitcnt <= send_bitcnt - 1;
- send_divcnt <= 0;
- end
- end
- end
+endmodule
+
+module simpleuart (
+ input clk,
+ input resetn,
+
+ output ser_tx,
+ input ser_rx,
+
+ input [3:0] reg_div_we,
+ input [31:0] reg_div_di,
+ output [31:0] reg_div_do,
+
+ input reg_dat_we,
+ input reg_dat_re,
+ input [31:0] reg_dat_di,
+ output [31:0] reg_dat_do,
+ output reg_dat_wait
+);
+ reg [31:0] cfg_divider;
+
+ reg [3:0] recv_state;
+ reg [31:0] recv_divcnt;
+ reg [7:0] recv_pattern;
+ reg [7:0] recv_buf_data;
+ reg recv_buf_valid;
+
+ reg [9:0] send_pattern;
+ reg [3:0] send_bitcnt;
+ reg [31:0] send_divcnt;
+ reg send_dummy;
+
+ assign reg_div_do = cfg_divider;
+
+ assign reg_dat_wait = reg_dat_we && (send_bitcnt || send_dummy);
+ assign reg_dat_do = recv_buf_valid ? recv_buf_data : ~0;
+
+ always @(posedge clk) begin
+ if (!resetn) begin
+ cfg_divider <= 1;
+ end else begin
+ if (reg_div_we[0]) cfg_divider[ 7: 0] <= reg_div_di[ 7: 0];
+ if (reg_div_we[1]) cfg_divider[15: 8] <= reg_div_di[15: 8];
+ if (reg_div_we[2]) cfg_divider[23:16] <= reg_div_di[23:16];
+ if (reg_div_we[3]) cfg_divider[31:24] <= reg_div_di[31:24];
+ end
+ end
+
+ always @(posedge clk) begin
+ if (!resetn) begin
+ recv_state <= 0;
+ recv_divcnt <= 0;
+ recv_pattern <= 0;
+ recv_buf_data <= 0;
+ recv_buf_valid <= 0;
+ end else begin
+ recv_divcnt <= recv_divcnt + 1;
+ if (reg_dat_re)
+ recv_buf_valid <= 0;
+ case (recv_state)
+ 0: begin
+ if (!ser_rx)
+ recv_state <= 1;
+ recv_divcnt <= 0;
+ end
+ 1: begin
+ if (2*recv_divcnt > cfg_divider) begin
+ recv_state <= 2;
+ recv_divcnt <= 0;
+ end
+ end
+ 10: begin
+ if (recv_divcnt > cfg_divider) begin
+ recv_buf_data <= recv_pattern;
+ recv_buf_valid <= 1;
+ recv_state <= 0;
+ end
+ end
+ default: begin
+ if (recv_divcnt > cfg_divider) begin
+ recv_pattern <= {ser_rx, recv_pattern[7:1]};
+ recv_state <= recv_state + 1;
+ recv_divcnt <= 0;
+ end
+ end
+ endcase
+ end
+ end
+
+ assign ser_tx = send_pattern[0];
+
+ always @(posedge clk) begin
+ if (reg_div_we)
+ send_dummy <= 1;
+ send_divcnt <= send_divcnt + 1;
+ if (!resetn) begin
+ send_pattern <= ~0;
+ send_bitcnt <= 0;
+ send_divcnt <= 0;
+ send_dummy <= 1;
+ end else begin
+ if (send_dummy && !send_bitcnt) begin
+ send_pattern <= ~0;
+ send_bitcnt <= 15;
+ send_divcnt <= 0;
+ send_dummy <= 0;
+ end else
+ if (reg_dat_we && !send_bitcnt) begin
+ send_pattern <= {1'b1, reg_dat_di[7:0], 1'b0};
+ send_bitcnt <= 10;
+ send_divcnt <= 0;
+ end else
+ if (send_divcnt > cfg_divider && send_bitcnt) begin
+ send_pattern <= {1'b1, send_pattern[9:1]};
+ send_bitcnt <= send_bitcnt - 1;
+ send_divcnt <= 0;
+ end
+ end
+ end
endmodule